diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6205c1098d1f9..7bb87b76e46f6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -31,6 +31,11 @@ updates: directory: "/" schedule: interval: "daily" + ignore: + # We use consistent go and node versions across a lot of different files, and updating via dependabot would cause + # drift among those files, instead we let renovate bot handle them. + - dependency-name: "library/golang" + - dependency-name: "library/node" - package-ecosystem: "docker" directory: "/test/container/" diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 5fe31bf6ca9f9..c34d16bed2675 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -13,7 +13,8 @@ on: env: # Golang version to use across CI steps - GOLANG_VERSION: '1.22' + # renovate: datasource=golang-version packageName=golang + GOLANG_VERSION: '1.23.3' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -31,7 +32,7 @@ jobs: docs: ${{ steps.filter.outputs.docs_any_changed }} steps: - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - - uses: tj-actions/changed-files@48d8f15b2aaa3d255ca5af3eba4870f807ce6b3c # v45.0.2 + - uses: tj-actions/changed-files@bab30c2299617f6615ec02a68b9a40d10bd21366 # v45.0.5 id: filter with: # Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file @@ -56,7 +57,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Download all Go modules @@ -77,11 +78,11 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Restore go build cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ~/.cache/go-build key: ${{ runner.os }}-go-build-v1-${{ github.run_id }} @@ -104,13 +105,14 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Run golangci-lint - uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0 + uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: - version: v1.58.2 + # renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?\d+)\.(?\d+)\.(?\d+)?$ + version: v1.62.2 args: --verbose test-go: @@ -131,7 +133,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -151,7 +153,7 @@ jobs: run: | echo "/usr/local/bin" >> $GITHUB_PATH - name: Restore go build cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ~/.cache/go-build key: ${{ runner.os }}-go-build-v1-${{ github.run_id }} @@ -172,7 +174,7 @@ jobs: - name: Run all unit tests run: make test-local - name: Generate test results artifacts - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: test-results path: test-results @@ -195,7 +197,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -215,7 +217,7 @@ jobs: run: | echo "/usr/local/bin" >> $GITHUB_PATH - name: Restore go build cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ~/.cache/go-build key: ${{ runner.os }}-go-build-v1-${{ github.run_id }} @@ -236,7 +238,7 @@ jobs: - name: Run all unit tests run: make test-race-local - name: Generate test results artifacts - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: race-results path: test-results/ @@ -251,7 +253,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Create symlink in GOPATH @@ -303,12 +305,13 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup NodeJS - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: - node-version: '21.6.1' + # renovate: datasource=node-version packageName=node versioning=node + node-version: '22.9.0' - name: Restore node dependency cache id: cache-dependencies - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ui/node_modules key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }} @@ -348,7 +351,7 @@ jobs: fetch-depth: 0 - name: Restore node dependency cache id: cache-dependencies - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ui/node_modules key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }} @@ -367,13 +370,13 @@ jobs: path: test-results - name: combine-go-coverage # We generate coverage reports for all Argo CD components, but only the applicationset-controller, - # app-controller, and repo-server report contain coverage data. The other components currently don't shut down - # gracefully, so no coverage data is produced. Once those components are fixed, we can add references to their - # coverage output directories. + # app-controller, repo-server, and commit-server report contain coverage data. The other components currently + # don't shut down gracefully, so no coverage data is produced. Once those components are fixed, we can add + # references to their coverage output directories. run: | - go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller -o test-results/full-coverage.out + go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller,e2e-code-coverage/commit-server -o test-results/full-coverage.out - name: Upload code coverage information to codecov.io - uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 with: file: test-results/full-coverage.out fail_ci_if_error: true @@ -381,7 +384,7 @@ jobs: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'argoproj/argo-cd' - uses: codecov/test-results-action@1b5b448b98e58ba90d1a1a1d9fcb72ca2263be46 # v1.0.0 + uses: codecov/test-results-action@9739113ad922ea0a9abb4b2c0f8bf6a4aa8ef820 # v1.0.1 with: file: test-results/junit.xml fail_ci_if_error: true @@ -390,7 +393,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - uses: SonarSource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 # v2.2 + uses: SonarSource/sonarqube-scan-action@1b442ee39ac3fa7c2acdd410208dcb2bcfaae6c4 # v4.1.0 if: env.sonar_secret != '' test-e2e: name: Run end-to-end tests @@ -400,14 +403,14 @@ jobs: fail-fast: false matrix: k3s: - - version: v1.30.2 + - version: v1.31.0 # We designate the latest version because we only collect code coverage for that version. latest: true - - version: v1.29.6 + - version: v1.30.4 latest: false - - version: v1.28.11 + - version: v1.29.8 latest: false - - version: v1.27.15 + - version: v1.28.13 latest: false needs: - build-go @@ -426,10 +429,17 @@ jobs: GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + large-packages: false + docker-images: false + swap-storage: false + tool-cache: false - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: GH actions workaround - Kill XSP4 process @@ -448,7 +458,7 @@ jobs: sudo chmod go-r $HOME/.kube/config kubectl version - name: Restore go build cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: ~/.cache/go-build key: ${{ runner.os }}-go-build-v1-${{ github.run_id }} @@ -506,13 +516,13 @@ jobs: goreman run stop-all || echo "goreman trouble" sleep 30 - name: Upload e2e coverage report - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: e2e-code-coverage path: /tmp/coverage if: ${{ matrix.k3s.latest }} - name: Upload e2e-server logs - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: e2e-server-k8s${{ matrix.k3s.version }}.log path: /tmp/e2e-server.log diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 530340127708c..1ebb6852bddcc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -33,7 +33,7 @@ jobs: # Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087 - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version-file: go.mod diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index f4b7a851816a8..426d2cbaa8cc0 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -17,11 +17,9 @@ on: platforms: required: true type: string - default: linux/amd64 push: required: true type: boolean - default: false target: required: false type: string @@ -69,15 +67,15 @@ jobs: if: ${{ github.ref_type != 'tag'}} - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ inputs.go-version }} - name: Install cosign - uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 - - uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 + - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Setup tags for container image as a CSV type run: | @@ -143,7 +141,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 #v6.7.0 + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 #v6.10.0 with: context: . platforms: ${{ inputs.platforms }} diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml index 3102e8361aa06..1894455ceea32 100644 --- a/.github/workflows/image.yaml +++ b/.github/workflows/image.yaml @@ -52,7 +52,8 @@ jobs: uses: ./.github/workflows/image-reuse.yaml with: # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) - go-version: 1.22 + # renovate: datasource=golang-version packageName=golang + go-version: 1.23.3 platforms: ${{ needs.set-vars.outputs.platforms }} push: false @@ -68,7 +69,8 @@ jobs: quay_image_name: quay.io/argoproj/argocd:latest ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }} # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) - go-version: 1.22 + # renovate: datasource=golang-version packageName=golang + go-version: 1.23.3 platforms: ${{ needs.set-vars.outputs.platforms }} push: true secrets: diff --git a/.github/workflows/pr-title-check.yml b/.github/workflows/pr-title-check.yml index 61c38548cf6ba..5c19a36a48140 100644 --- a/.github/workflows/pr-title-check.yml +++ b/.github/workflows/pr-title-check.yml @@ -23,7 +23,7 @@ jobs: name: Validate PR Title runs-on: ubuntu-latest steps: - - uses: thehanimo/pr-title-checker@1d8cd483a2b73118406a187f54dca8a9415f1375 # v1.4.2 + - uses: thehanimo/pr-title-checker@7fbfe05602bdd86f926d3fb3bccb6f3aed43bc70 # v1.4.3 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} configuration_path: ".github/pr-title-checker-config.json" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a30e44ec0ec7a..9629af2581fa2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,7 +10,8 @@ on: permissions: {} env: - GOLANG_VERSION: '1.22' # Note: go-version must also be set in job argocd-image.with.go-version + # renovate: datasource=golang-version packageName=golang + GOLANG_VERSION: '1.23.3' # Note: go-version must also be set in job argocd-image.with.go-version jobs: argocd-image: @@ -23,7 +24,8 @@ jobs: with: quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }} # Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations) - go-version: 1.22 + # renovate: datasource=golang-version packageName=golang + go-version: 1.23.3 platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le push: true secrets: @@ -67,20 +69,16 @@ jobs: - name: Fetch all tags run: git fetch --force --tags - - name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in realease branches. - run: | - set -xue - if echo ${{ github.ref_name }} | grep -E -- '-rc1+$';then - echo "GORELEASER_PREVIOUS_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | tail -n 2 | head -n 1)" >> $GITHUB_ENV - else - echo "This is not the first release on the branch, Using GoReleaser defaults" - fi - - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} + - name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in release branches. + run: | + set -xue + echo "GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }})" >> $GITHUB_ENV + - name: Set environment variables for ldflags id: set_ldflag run: | @@ -96,14 +94,14 @@ jobs: tool-cache: false - name: Run GoReleaser - uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 + uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 id: run-goreleaser with: version: latest args: release --clean --timeout 55m env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - KUBECTL_VERSION: ${{ env.KUBECTL_VERSION }} + KUBECTL_VERSION: ${{ env.KUBECTL_VERSION }} GIT_TREE_STATE: ${{ env.GIT_TREE_STATE }} - name: Generate subject for provenance @@ -153,7 +151,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ env.GOLANG_VERSION }} @@ -186,7 +184,7 @@ jobs: fi cd /tmp && tar -zcf sbom.tar.gz *.spdx - + - name: Generate SBOM hash shell: bash id: sbom-hash @@ -195,15 +193,15 @@ jobs: # base64 -w0 encodes to base64 and outputs on a single line. # sha256sum /tmp/sbom.tar.gz ... | base64 -w0 echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT" - + - name: Upload SBOM - uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8 + uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: | /tmp/sbom.tar.gz - + sbom-provenance: needs: [generate-sbom] permissions: @@ -211,13 +209,13 @@ jobs: id-token: write # Needed for provenance signing and ID contents: write # Needed for release uploads if: github.repository == 'argoproj/argo-cd' - # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator + # Must be referenced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 with: base64-subjects: "${{ needs.generate-sbom.outputs.hashes }}" provenance-name: "argocd-sbom.intoto.jsonl" upload-assets: true - + post-release: needs: - argocd-image diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 6975868f4a78a..0403b1e2d8ca1 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -54,7 +54,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif diff --git a/.gitignore b/.gitignore index cc5a439491dbb..f9f123e46676b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .vscode/ .idea/ .DS_Store +.run/ vendor/ dist/* ui/dist/app/* diff --git a/.golangci.yaml b/.golangci.yaml index 2140cf08a7bd9..5333f86b47f94 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -18,10 +18,13 @@ linters: - govet - ineffassign - misspell + - perfsprint - staticcheck - testifylint + - thelper - unparam - unused + - usestdlibvars - whitespace linters-settings: gocritic: @@ -37,6 +40,17 @@ linters-settings: - typeSwitchVar goimports: local-prefixes: github.com/argoproj/argo-cd/v2 + perfsprint: + # Optimizes even if it requires an int or uint type cast. + int-conversion: true + # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. + err-error: false + # Optimizes `fmt.Errorf`. + errorf: false + # Optimizes `fmt.Sprintf` with only one argument. + sprintf1: true + # Optimizes into strings concatenation. + strconcat: false testifylint: enable-all: true disable: diff --git a/.mockery.yaml b/.mockery.yaml index 3a8b437ef347d..a2af16e826166 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -26,6 +26,13 @@ packages: github.com/argoproj/argo-cd/v2/applicationset/utils: interfaces: Renderer: + github.com/argoproj/argo-cd/v2/commitserver/commit: + interfaces: + RepoClientFactory: + github.com/argoproj/argo-cd/v2/commitserver/apiclient: + interfaces: + CommitServiceClient: + Clientset: github.com/argoproj/argo-cd/v2/controller/cache: interfaces: LiveStateCache: diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 3d69498d27c09..71bd86159aeb3 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,4 +8,4 @@ python: build: os: "ubuntu-22.04" tools: - python: "3.7" + python: "3.12" diff --git a/Dockerfile b/Dockerfile index bc4e6debbfaa1..45c1deb4d8c9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8 # Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image # Also used as the image in CI jobs so needs all dependencies #################################################################################################### -FROM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS builder +FROM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS builder RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list @@ -83,7 +83,7 @@ WORKDIR /home/argocd #################################################################################################### # Argo CD UI stage #################################################################################################### -FROM --platform=$BUILDPLATFORM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 AS argocd-ui +FROM --platform=$BUILDPLATFORM docker.io/library/node:23.0.0@sha256:e643c0b70dca9704dff42e12b17f5b719dbe4f95e6392fc2dfa0c5f02ea8044d AS argocd-ui WORKDIR /src COPY ["ui/package.json", "ui/yarn.lock", "./"] @@ -101,7 +101,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP #################################################################################################### # Argo CD Build stage which performs the actual build of Argo CD binaries #################################################################################################### -FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS argocd-build +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.23.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS argocd-build WORKDIR /go/src/github.com/argoproj/argo-cd @@ -140,7 +140,8 @@ RUN ln -s /usr/local/bin/argocd /usr/local/bin/argocd-server && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-dex && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-notifications && \ ln -s /usr/local/bin/argocd /usr/local/bin/argocd-applicationset-controller && \ - ln -s /usr/local/bin/argocd /usr/local/bin/argocd-k8s-auth + ln -s /usr/local/bin/argocd /usr/local/bin/argocd-k8s-auth && \ + ln -s /usr/local/bin/argocd /usr/local/bin/argocd-commit-server USER $ARGOCD_USER_ID ENTRYPOINT ["/usr/bin/tini", "--"] diff --git a/Makefile b/Makefile index d6f8cdf62d5d8..8cc1b928dad83 100644 --- a/Makefile +++ b/Makefile @@ -472,6 +472,7 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local mkdir -p /tmp/coverage/repo-server mkdir -p /tmp/coverage/applicationset-controller mkdir -p /tmp/coverage/notification + mkdir -p /tmp/coverage/commit-server # set paths for locally managed ssh known hosts and tls certs data ARGOCD_SSH_DATA_PATH=/tmp/argo-e2e/app/config/ssh \ ARGOCD_TLS_DATA_PATH=/tmp/argo-e2e/app/config/tls \ @@ -486,8 +487,10 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local BIN_MODE=$(ARGOCD_BIN_MODE) \ ARGOCD_APPLICATION_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ + ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE=true \ ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \ ARGOCD_E2E_TEST=true \ + ARGOCD_HYDRATOR_ENABLED=true \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} ls -lrt /tmp/coverage diff --git a/Procfile b/Procfile index fd955a39ac416..9ff5e67236088 100644 --- a/Procfile +++ b/Procfile @@ -1,9 +1,10 @@ -controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/app-controller} HOSTNAME=testappcontroller-1 FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'}" -api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/api-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" +controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/app-controller} HOSTNAME=testappcontroller-1 FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --commit-server localhost:${ARGOCD_E2E_COMMITSERVER_PORT:-8086} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'} --hydrator-enabled=${ARGOCD_HYDRATOR_ENABLED:='false'}" +api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/api-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --hydrator-enabled=${ARGOCD_HYDRATOR_ENABLED:='false'}" dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/cmd gendexcfg -o `pwd`/dist/dex.yaml && (test -f dist/dex.yaml || { echo 'Failed to generate dex configuration'; exit 1; }) && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:$(grep "image: ghcr.io/dexidp/dex" manifests/base/dex/argocd-dex-server-deployment.yaml | cut -d':' -f3) dex serve /dex.yaml" redis: hack/start-redis-with-password.sh repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/repo-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-repo-server ARGOCD_GPG_ENABLED=${ARGOCD_GPG_ENABLED:-false} $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --otlp-address=${ARGOCD_OTLP_ADDRESS}" cmp-server: [ "$ARGOCD_E2E_TEST" = 'true' ] && exit 0 || [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-cmp-server ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} $COMMAND --config-dir-path ./test/cmp --loglevel debug --otlp-address=${ARGOCD_OTLP_ADDRESS}" +commit-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/commit-server} FORCE_LOG_COLORS=1 ARGOCD_BINARY_NAME=argocd-commit-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_COMMITSERVER_PORT:-8086}" ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start' git-server: test/fixture/testrepos/start-git.sh helm-registry: test/fixture/testrepos/start-helm-registry.sh diff --git a/README.md b/README.md index bea5c645c328c..b369043821010 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Participation in the Argo CD project is governed by the [CNCF Code of Conduct](h ### Blogs and Presentations 1. [Awesome-Argo: A Curated List of Awesome Projects and Resources Related to Argo](https://github.com/terrytangyuan/awesome-argo) -1. [Unveil the Secret Ingredients of Continuous Delivery at Enterprise Scale with Argo CD](https://akuity.io/blog/unveil-the-secret-ingredients-of-continuous-delivery-at-enterprise-scale-with-argocd-kubecon-china-2021/) +1. [Unveil the Secret Ingredients of Continuous Delivery at Enterprise Scale with Argo CD](https://akuity.io/blog/secret-ingredients-of-continuous-delivery-at-enterprise-scale-with-argocd/) 1. [GitOps Without Pipelines With ArgoCD Image Updater](https://youtu.be/avPUQin9kzU) 1. [Combining Argo CD (GitOps), Crossplane (Control Plane), And KubeVela (OAM)](https://youtu.be/eEcgn_gU3SM) 1. [How to Apply GitOps to Everything - Combining Argo CD and Crossplane](https://youtu.be/yrj4lmScKHQ) diff --git a/USERS.md b/USERS.md index ab5dbc8c745c1..ef200ecb3a362 100644 --- a/USERS.md +++ b/USERS.md @@ -16,6 +16,8 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Adyen](https://www.adyen.com) 1. [AirQo](https://airqo.net/) 1. [Akuity](https://akuity.io/) +1. [Alarm.com](https://alarm.com/) +1. [Alauda](https://alauda.io/) 1. [Albert Heijn](https://ah.nl/) 1. [Alibaba Group](https://www.alibabagroup.com/) 1. [Allianz Direct](https://www.allianzdirect.de/) @@ -35,12 +37,14 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Axians ACSP](https://www.axians.fr) 1. [Axual B.V.](https://axual.com) 1. [Back Market](https://www.backmarket.com) +1. [Bajaj Finserv Health Ltd.](https://www.bajajfinservhealth.in) 1. [Baloise](https://www.baloise.com) 1. [BCDevExchange DevOps Platform](https://bcdevexchange.org/DevOpsPlatform) 1. [Beat](https://thebeat.co/en/) 1. [Beez Innovation Labs](https://www.beezlabs.com/) 1. [Bedag Informatik AG](https://www.bedag.ch/) 1. [Beleza Na Web](https://www.belezanaweb.com.br/) +1. [Believable Bots](https://believablebots.io) 1. [BigPanda](https://bigpanda.io) 1. [BioBox Analytics](https://biobox.io) 1. [BMW Group](https://www.bmwgroup.com/) @@ -75,6 +79,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Codility](https://www.codility.com/) 1. [Cognizant](https://www.cognizant.com/) 1. [Commonbond](https://commonbond.co/) +1. [Compatio.AI](https://compatio.ai/) 1. [Contlo](https://contlo.com/) 1. [Coralogix](https://coralogix.com/) 1. [Crédit Agricole CIB](https://www.ca-cib.com) @@ -84,6 +89,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [D2iQ](https://www.d2iq.com) 1. [DaoCloud](https://daocloud.io/) 1. [Datarisk](https://www.datarisk.io/) +1. [Daydream](https://daydream.ing) 1. [Deloitte](https://www.deloitte.com/) 1. [Deutsche Telekom AG](https://telekom.com) 1. [Devopsi - Poland Software/DevOps Consulting](https://devopsi.pl/) @@ -114,6 +120,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [freee](https://corp.freee.co.jp/en/company/) 1. [Freshop, Inc](https://www.freshop.com/) 1. [Future PLC](https://www.futureplc.com/) +1. [Flagler Health](https://www.flaglerhealth.io/) 1. [G DATA CyberDefense AG](https://www.gdata-software.com/) 1. [G-Research](https://www.gresearch.com/teams/open-source-software/) 1. [Garner](https://www.garnercorp.com) @@ -242,6 +249,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Optoro](https://www.optoro.com/) 1. [Orbital Insight](https://orbitalinsight.com/) 1. [Oscar Health Insurance](https://hioscar.com/) +1. [Outpost24](https://outpost24.com/) 1. [p3r](https://www.p3r.one/) 1. [Packlink](https://www.packlink.com/) 1. [PagerDuty](https://www.pagerduty.com/) @@ -270,6 +278,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [PT Boer Technology (Btech)](https://btech.id/) 1. [PUBG](https://www.pubg.com) 1. [Puzzle ITC](https://www.puzzle.ch/) +1. [Pvotal Technologies](https://pvotal.tech/) 1. [Qonto](https://qonto.com) 1. [QuintoAndar](https://quintoandar.com.br) 1. [Quipper](https://www.quipper.com/) @@ -326,14 +335,17 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Swisscom](https://www.swisscom.ch) 1. [Swissquote](https://github.com/swissquote) 1. [Syncier](https://syncier.com/) +1. [Synergy](https://synergy.net.au) 1. [Syself](https://syself.com) 1. [TableCheck](https://tablecheck.com/) 1. [Tailor Brands](https://www.tailorbrands.com) 1. [Tamkeen Technologies](https://tamkeentech.sa/) +1. [TBC Bank](https://tbcbank.ge/) 1. [Techcombank](https://www.techcombank.com.vn/trang-chu) 1. [Technacy](https://www.technacy.it/) 1. [Telavita](https://www.telavita.com.br/) 1. [Tesla](https://tesla.com/) +1. [TextNow](https://www.textnow.com/) 1. [The Scale Factory](https://www.scalefactory.com/) 1. [ThousandEyes](https://www.thousandeyes.com/) 1. [Ticketmaster](https://ticketmaster.com) @@ -381,4 +393,5 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Yubo](https://www.yubo.live/) 1. [ZDF](https://www.zdf.de/) 1. [Zimpler](https://www.zimpler.com/) +1. [ZipRecuiter](https://www.ziprecruiter.com/) 1. [ZOZO](https://corp.zozo.com/) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index d3911f1e0c7c4..1993279e2385b 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -18,7 +18,9 @@ import ( "context" "fmt" "reflect" + "runtime/debug" "sort" + "strconv" "strings" "time" @@ -52,7 +54,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/db" argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" argoutil "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" @@ -79,7 +80,6 @@ type ApplicationSetReconciler struct { Recorder record.EventRecorder Generators map[string]generators.Generator ArgoDB db.ArgoDB - ArgoAppClientset appclientset.Interface KubeClientset kubernetes.Interface Policy argov1alpha1.ApplicationsSyncPolicy EnablePolicyOverride bool @@ -96,9 +96,22 @@ type ApplicationSetReconciler struct { // +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets/status,verbs=get;update;patch -func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, err error) { + startReconcile := time.Now() logCtx := log.WithField("applicationset", req.NamespacedName) + defer func() { + if rec := recover(); rec != nil { + logCtx.Errorf("Recovered from panic: %+v\n%s", rec, debug.Stack()) + result = ctrl.Result{} + var ok bool + err, ok = rec.(error) + if !ok { + err = fmt.Errorf("%v", r) + } + } + }() + var applicationSetInfo argov1alpha1.ApplicationSet parametersGenerated := false startTime := time.Now() @@ -334,7 +347,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque requeueAfter = ReconcileRequeueOnValidationError } - logCtx.WithField("requeueAfter", requeueAfter).Info("end reconcile") + logCtx.WithField("requeueAfter", requeueAfter).Info("end reconcile in ", time.Since(startReconcile)) return ctrl.Result{ RequeueAfter: requeueAfter, @@ -472,7 +485,9 @@ func (r *ApplicationSetReconciler) validateGeneratedApplications(ctx context.Con errorsByIndex[i] = fmt.Errorf("ApplicationSet %s contains applications with duplicate name: %s", applicationSetInfo.Name, app.Name) continue } - _, err := r.ArgoAppClientset.ArgoprojV1alpha1().AppProjects(r.ArgoCDNamespace).Get(ctx, app.Spec.GetProject(), metav1.GetOptions{}) + + appProject := &argov1alpha1.AppProject{} + err := r.Client.Get(ctx, types.NamespacedName{Name: app.Spec.Project, Namespace: r.ArgoCDNamespace}, appProject) if err != nil { if apierr.IsNotFound(err) { errorsByIndex[i] = fmt.Errorf("application references project %s which does not exist", app.Spec.Project) @@ -994,7 +1009,7 @@ func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1al } func progressiveSyncsRollingSyncStrategyEnabled(appset *argov1alpha1.ApplicationSet) bool { - return appset.Spec.Strategy != nil && appset.Spec.Strategy.RollingSync != nil && appset.Spec.Strategy.Type == "RollingSync" + return appset.Spec.Strategy != nil && appset.Spec.Strategy.RollingSync != nil && appset.Spec.Strategy.Type == "RollingSync" && len(appset.Spec.Strategy.RollingSync.Steps) > 0 } func isApplicationHealthy(app argov1alpha1.Application) bool { @@ -1017,6 +1032,16 @@ func statusStrings(app argov1alpha1.Application) (string, string, string) { return healthStatusString, syncStatusString, operationPhaseString } +func getAppStep(appName string, appStepMap map[string]int) int { + // if an application is not selected by any match expression, it defaults to step -1 + step := -1 + if appStep, ok := appStepMap[appName]; ok { + // 1-based indexing + step = appStep + 1 + } + return step +} + // check the status of each Application's status and promote Applications to the next status if needed func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, appStepMap map[string]int) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { now := metav1.Now() @@ -1036,7 +1061,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con LastTransitionTime: &now, Message: "No Application status found, defaulting status to Waiting.", Status: "Waiting", - Step: fmt.Sprint(appStepMap[app.Name] + 1), + Step: strconv.Itoa(getAppStep(app.Name, appStepMap)), TargetRevisions: app.Status.GetRevisions(), } } else { @@ -1061,7 +1086,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Waiting" currentAppStatus.Message = "Application has pending changes, setting status to Waiting." - currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) + currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap)) currentAppStatus.TargetRevisions = app.Status.GetRevisions() } @@ -1079,14 +1104,14 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Progressing" currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing." - currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) + currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap)) } } else if operationPhaseString == "Running" || healthStatusString == "Progressing" { logCtx.Infof("Application %v has entered Progressing status, updating its ApplicationSet status to Progressing", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Progressing" currentAppStatus.Message = "Application resource became Progressing, updating status from Pending to Progressing." - currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) + currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap)) } } @@ -1095,7 +1120,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = healthStatusString currentAppStatus.Message = "Application resource is already Healthy, updating status from Waiting to Healthy." - currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) + currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap)) } if currentAppStatus.Status == "Progressing" && isApplicationHealthy(app) { @@ -1103,7 +1128,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = healthStatusString currentAppStatus.Message = "Application resource became Healthy, updating status from Progressing to Healthy." - currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) + currentAppStatus.Step = strconv.Itoa(getAppStep(currentAppStatus.Application, appStepMap)) } appStatuses = append(appStatuses, currentAppStatus) @@ -1124,14 +1149,12 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress appStatuses := make([]argov1alpha1.ApplicationSetApplicationStatus, 0, len(applicationSet.Status.ApplicationStatus)) // if we have no RollingUpdate steps, clear out the existing ApplicationStatus entries - if applicationSet.Spec.Strategy != nil && applicationSet.Spec.Strategy.Type != "" && applicationSet.Spec.Strategy.Type != "AllAtOnce" { + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { updateCountMap := []int{} totalCountMap := []int{} - length := 0 - if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { - length = len(applicationSet.Spec.Strategy.RollingSync.Steps) - } + length := len(applicationSet.Spec.Strategy.RollingSync.Steps) + for s := 0; s < length; s++ { updateCountMap = append(updateCountMap, 0) totalCountMap = append(totalCountMap, 0) @@ -1141,10 +1164,8 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress for _, appStatus := range applicationSet.Status.ApplicationStatus { totalCountMap[appStepMap[appStatus.Application]] += 1 - if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { - if appStatus.Status == "Pending" || appStatus.Status == "Progressing" { - updateCountMap[appStepMap[appStatus.Application]] += 1 - } + if appStatus.Status == "Pending" || appStatus.Status == "Progressing" { + updateCountMap[appStepMap[appStatus.Application]] += 1 } } @@ -1169,7 +1190,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress if updateCountMap[appStepMap[appStatus.Application]] >= maxUpdateVal { maxUpdateAllowed = false - logCtx.Infof("Application %v is not allowed to update yet, %v/%v Applications already updating in step %v in AppSet %v", appStatus.Application, updateCountMap[appStepMap[appStatus.Application]], maxUpdateVal, appStepMap[appStatus.Application]+1, applicationSet.Name) + logCtx.Infof("Application %v is not allowed to update yet, %v/%v Applications already updating in step %v in AppSet %v", appStatus.Application, updateCountMap[appStepMap[appStatus.Application]], maxUpdateVal, getAppStep(appStatus.Application, appStepMap), applicationSet.Name) } } @@ -1178,7 +1199,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress appStatus.LastTransitionTime = &now appStatus.Status = "Pending" appStatus.Message = "Application moved to Pending status, watching for the Application resource to start Progressing." - appStatus.Step = fmt.Sprint(appStepMap[appStatus.Application] + 1) + appStatus.Step = strconv.Itoa(getAppStep(appStatus.Application, appStepMap)) updateCountMap[appStepMap[appStatus.Application]] += 1 } @@ -1484,7 +1505,7 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs { return false } requeue := shouldRequeueApplicationSet(appOld, appNew, enableProgressiveSyncs) - logCtx.WithField("requeue", requeue).Debugf("requeue: %t caused by application %s\n", requeue, appNew.Name) + logCtx.WithField("requeue", requeue).Debugf("requeue: %t caused by application %s", requeue, appNew.Name) return requeue }, GenericFunc: func(e event.GenericEvent) bool { diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 02608175245b4..c9e7a4f42db19 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -36,8 +36,8 @@ import ( "github.com/argoproj/argo-cd/v2/applicationset/utils" appsetmetrics "github.com/argoproj/argo-cd/v2/applicationset/metrics" + argocommon "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/argo-cd/v2/pkg/apis/application" @@ -48,9 +48,6 @@ func TestCreateOrUpdateInCluster(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, c := range []struct { // name is human-readable test name name string @@ -1091,9 +1088,6 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, c := range []struct { // name is human-readable test name name string @@ -1157,7 +1151,7 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { Name: "my-secret", Namespace: "namespace", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, Data: map[string][]byte{ @@ -1184,18 +1178,18 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { // argoDB := db.NewDB("namespace", settingsMgr, r.KubeClientset) // clusterList, err := argoDB.ListClusters(context.Background()) clusterList, err := utils.ListClusters(context.Background(), kubeclientset, "namespace") - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) // App on the cluster should have the expected finalizers assert.ElementsMatch(t, c.expectedFinalizers, retrievedApp.Finalizers) @@ -1214,9 +1208,6 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, c := range []struct { // name is human-readable test name name string @@ -1316,7 +1307,7 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { Name: "my-secret", Namespace: "namespace", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, Data: map[string][]byte{ @@ -1343,18 +1334,18 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { // argoDB := db.NewDB("argocd", settingsMgr, r.KubeClientset) // clusterList, err := argoDB.ListClusters(context.Background()) clusterList, err := utils.ListClusters(context.Background(), kubeclientset, "namespace") - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) finalizerRemoved := len(retrievedApp.Finalizers) == 0 @@ -1371,9 +1362,6 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, c := range []struct { // name is human-readable test name name string @@ -1414,7 +1402,7 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { } err := controllerutil.SetControllerReference(&appSet, &app, scheme) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) initObjs := []crtclient.Object{&app, &appSet} @@ -1430,11 +1418,11 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { } err = r.removeOwnerReferencesOnDeleteAppSet(context.Background(), appSet) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - require.NoError(t, err, "Unexpected error") + require.NoError(t, err) ownerReferencesRemoved := len(retrievedApp.OwnerReferences) == 0 assert.True(t, ownerReferencesRemoved) @@ -1447,9 +1435,6 @@ func TestCreateApplications(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - testCases := []struct { name string appSet v1alpha1.ApplicationSet @@ -1653,8 +1638,6 @@ func TestDeleteInCluster(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) for _, c := range []struct { // appSet is the application set on which the delete function is called @@ -1800,7 +1783,7 @@ func TestDeleteInCluster(t *testing.T) { Name: obj.Name, }, got) - assert.EqualError(t, err, fmt.Sprintf("applications.argoproj.io \"%s\" not found", obj.Name)) + assert.EqualError(t, err, fmt.Sprintf("applications.argoproj.io %q not found", obj.Name)) } } } @@ -1809,8 +1792,6 @@ func TestGetMinRequeueAfter(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) @@ -1913,18 +1894,6 @@ func TestValidateGeneratedApplications(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - - client := fake.NewClientBuilder().WithScheme(scheme).Build() - metrics := appsetmetrics.NewFakeAppsetMetrics(client) - - // Valid cluster - myCluster := v1alpha1.Cluster{ - Server: "https://kubernetes.default.svc", - Name: "my-cluster", - } - // Valid project myProject := &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "namespace"}, @@ -1945,6 +1914,9 @@ func TestValidateGeneratedApplications(t *testing.T) { }, } + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(myProject).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) + // Test a subset of the validations that 'validateGeneratedApplications' performs for _, cc := range []struct { name string @@ -2075,7 +2047,7 @@ func TestValidateGeneratedApplications(t *testing.T) { Name: "my-secret", Namespace: "namespace", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, Data: map[string][]byte{ @@ -2088,27 +2060,15 @@ func TestValidateGeneratedApplications(t *testing.T) { objects := append([]runtime.Object{}, secret) kubeclientset := kubefake.NewSimpleClientset(objects...) - argoDBMock := dbmocks.ArgoDB{} - argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil) - argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ - myCluster, - }}, nil) - - argoObjs := []runtime.Object{myProject} - for _, app := range cc.apps { - argoObjs = append(argoObjs, &app) - } - r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoCDNamespace: "namespace", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + ArgoCDNamespace: "namespace", + KubeClientset: kubeclientset, + Metrics: metrics, } appSetInfo := v1alpha1.ApplicationSet{} @@ -2150,8 +2110,6 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) project := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "good-project", Namespace: "argocd"}, @@ -2189,18 +2147,9 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { } kubeclientset := kubefake.NewSimpleClientset() - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&project} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &project).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) - goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} - badCluster := v1alpha1.Cluster{Server: "https://bad-cluster", Name: "bad-cluster"} - argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) - argoDBMock.On("GetCluster", mock.Anything, "https://bad-cluster").Return(&badCluster, nil) - argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ - goodCluster, - }}, nil) r := ApplicationSetReconciler{ Client: client, @@ -2210,12 +2159,11 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Policy: v1alpha1.ApplicationsSyncPolicySync, - ArgoCDNamespace: "argocd", - Metrics: metrics, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Policy: v1alpha1.ApplicationsSyncPolicySync, + ArgoCDNamespace: "argocd", + Metrics: metrics, } req := ctrl.Request{ @@ -2246,8 +2194,6 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) testCases := []struct { appset v1alpha1.ApplicationSet @@ -2280,6 +2226,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { }, }, testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + t.Helper() assert.Len(t, appset.Status.Conditions, 3) }, }, @@ -2315,6 +2262,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { }, }, testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + t.Helper() assert.Len(t, appset.Status.Conditions, 3) isProgressingCondition := false @@ -2377,6 +2325,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { }, }, testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + t.Helper() assert.Len(t, appset.Status.Conditions, 4) isProgressingCondition := false @@ -2394,8 +2343,6 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { } kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} for _, testCase := range testCases { client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&testCase.appset).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).WithStatusSubresource(&testCase.appset).Build() @@ -2409,10 +2356,9 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } for _, condition := range testCase.conditions { @@ -2425,11 +2371,10 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { } func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.Application { + t.Helper() scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, @@ -2467,17 +2412,28 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, } - kubeclientset := kubefake.NewSimpleClientset() - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&defaultProject} + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Namespace: "argocd", + Labels: map[string]string{ + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + // Since this test requires the cluster to be an invalid destination, we + // always return a cluster named 'my-cluster2' (different from app 'my-cluster', above) + "name": []byte("good-cluster"), + "server": []byte("https://good-cluster"), + "config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"), + }, + } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) + + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) - goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} - argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) - argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ - goodCluster, - }}, nil) r := ApplicationSetReconciler{ Client: client, @@ -2487,9 +2443,8 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "argocd", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, @@ -2590,11 +2545,10 @@ func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t } func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.ApplicationList { + t.Helper() scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, @@ -2632,17 +2586,28 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, } - kubeclientset := kubefake.NewSimpleClientset() - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&defaultProject} + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Namespace: "argocd", + Labels: map[string]string{ + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + // Since this test requires the cluster to be an invalid destination, we + // always return a cluster named 'my-cluster2' (different from app 'my-cluster', above) + "name": []byte("good-cluster"), + "server": []byte("https://good-cluster"), + "config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"), + }, + } + + objects := append([]runtime.Object{}, secret) + kubeclientset := kubefake.NewSimpleClientset(objects...) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) - goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} - argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) - argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ - goodCluster, - }}, nil) r := ApplicationSetReconciler{ Client: client, @@ -2652,9 +2617,8 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, + ArgoDB: &dbmocks.ArgoDB{}, ArgoCDNamespace: "argocd", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, @@ -2728,7 +2692,7 @@ func TestDeletePerformedWithSyncPolicyCreateDelete(t *testing.T) { apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) - assert.Empty(t, apps.Items) + assert.NotNil(t, apps.Items[0].DeletionTimestamp) } func TestDeletePerformedWithSyncPolicySync(t *testing.T) { @@ -2736,7 +2700,7 @@ func TestDeletePerformedWithSyncPolicySync(t *testing.T) { apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) - assert.Empty(t, apps.Items) + assert.NotNil(t, apps.Items[0].DeletionTimestamp) } func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) { @@ -2744,7 +2708,7 @@ func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, false) - assert.Empty(t, apps.Items) + assert.NotNil(t, apps.Items[0].DeletionTimestamp) } func TestPolicies(t *testing.T) { @@ -2752,22 +2716,12 @@ func TestPolicies(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://kubernetes.default.svc"}}}, } - myCluster := v1alpha1.Cluster{ - Server: "https://kubernetes.default.svc", - Name: "my-cluster", - } kubeclientset := kubefake.NewSimpleClientset() - argoDBMock := dbmocks.ArgoDB{} - argoDBMock.On("GetCluster", mock.Anything, "https://kubernetes.default.svc").Return(&myCluster, nil) - argoObjs := []runtime.Object{&defaultProject} for _, c := range []struct { name string @@ -2839,7 +2793,7 @@ func TestPolicies(t *testing.T) { }, } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet, &defaultProject).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ @@ -2850,12 +2804,11 @@ func TestPolicies(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, - ArgoCDNamespace: "argocd", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Policy: policy, - Metrics: metrics, + ArgoDB: &dbmocks.ArgoDB{}, + ArgoCDNamespace: "argocd", + KubeClientset: kubeclientset, + Policy: policy, + Metrics: metrics, } req := ctrl.Request{ @@ -2923,12 +2876,8 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} for _, cc := range []struct { name string @@ -3012,10 +2961,9 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } err = r.setAppSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) @@ -3031,9 +2979,6 @@ func TestBuildAppDependencyList(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - client := fake.NewClientBuilder().WithScheme(scheme).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) @@ -3765,18 +3710,15 @@ func TestBuildAppDependencyList(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } appDependencyList, appStepMap := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps) @@ -3791,9 +3733,6 @@ func TestBuildAppSyncMap(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - client := fake.NewClientBuilder().WithScheme(scheme).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) @@ -3813,8 +3752,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -3830,8 +3778,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -3853,8 +3810,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -3876,8 +3842,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -3945,8 +3920,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4014,8 +3998,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4083,8 +4076,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4152,8 +4154,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4221,8 +4232,17 @@ func TestBuildAppSyncMap(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4356,18 +4376,15 @@ func TestBuildAppSyncMap(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } appSyncMap := r.buildAppSyncMap(cc.appSet, cc.appDependencyList, cc.appMap) @@ -4381,9 +4398,6 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, cc := range []struct { name string appSet v1alpha1.ApplicationSet @@ -4400,8 +4414,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -4417,8 +4440,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -4440,6 +4472,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4459,8 +4494,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{}, @@ -4483,6 +4527,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4502,8 +4549,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4535,6 +4591,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4554,8 +4613,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4601,6 +4669,10 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + "app2-multisource": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4627,8 +4699,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4655,6 +4736,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4674,8 +4758,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4708,6 +4801,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4727,8 +4823,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4761,6 +4866,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4780,8 +4888,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4814,6 +4931,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4833,8 +4953,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, }, @@ -4883,8 +5012,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -4933,6 +5071,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4952,8 +5093,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -5002,6 +5152,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5021,8 +5174,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -5070,6 +5232,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5089,8 +5254,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, Spec: v1alpha1.ApplicationSetSpec{ Strategy: &v1alpha1.ApplicationSetStrategy{ - Type: "RollingSync", - RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{}, + }, + }, + }, }, }, Status: v1alpha1.ApplicationSetStatus{ @@ -5130,6 +5304,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5143,21 +5320,18 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) @@ -5178,9 +5352,6 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, cc := range []struct { name string appSet v1alpha1.ApplicationSet @@ -5897,21 +6068,18 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap) @@ -5932,9 +6100,6 @@ func TestUpdateResourceStatus(t *testing.T) { err := v1alpha1.AddToScheme(scheme) require.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - require.NoError(t, err) - for _, cc := range []struct { name string appSet v1alpha1.ApplicationSet @@ -6113,21 +6278,18 @@ func TestUpdateResourceStatus(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) @@ -6205,21 +6367,18 @@ func TestResourceStatusAreOrdered(t *testing.T) { } { t.Run(cc.name, func(t *testing.T) { kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{}, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Metrics: metrics, + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &dbmocks.ArgoDB{}, + KubeClientset: kubeclientset, + Metrics: metrics, } err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) diff --git a/applicationset/controllers/clustereventhandler.go b/applicationset/controllers/clustereventhandler.go index 66fdebca66a21..363fc03f16694 100644 --- a/applicationset/controllers/clustereventhandler.go +++ b/applicationset/controllers/clustereventhandler.go @@ -14,7 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" - "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/common" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -50,7 +50,7 @@ type addRateLimitingInterface[T comparable] interface { func (h *clusterSecretEventHandler) queueRelatedAppGenerators(ctx context.Context, q addRateLimitingInterface[reconcile.Request], object client.Object) { // Check for label, lookup all ApplicationSets that might match the cluster, queue them all - if object.GetLabels()[generators.ArgoCDSecretTypeLabel] != generators.ArgoCDSecretTypeCluster { + if object.GetLabels()[common.LabelKeySecretType] != common.LabelValueSecretTypeCluster { return } diff --git a/applicationset/controllers/clustereventhandler_test.go b/applicationset/controllers/clustereventhandler_test.go index 1f73ab36746f2..8af4b1c17d49b 100644 --- a/applicationset/controllers/clustereventhandler_test.go +++ b/applicationset/controllers/clustereventhandler_test.go @@ -4,6 +4,8 @@ import ( "context" "testing" + argocommon "github.com/argoproj/argo-cd/v2/common" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -16,7 +18,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/argoproj/argo-cd/v2/applicationset/generators" argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -42,7 +43,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -70,7 +71,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -113,7 +114,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -157,7 +158,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -218,7 +219,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -254,7 +255,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -304,7 +305,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -355,7 +356,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -389,7 +390,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -425,7 +426,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -475,7 +476,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, @@ -526,7 +527,7 @@ func TestClusterEventHandler(t *testing.T) { Namespace: "argocd", Name: "my-secret", Labels: map[string]string{ - generators.ArgoCDSecretTypeLabel: generators.ArgoCDSecretTypeCluster, + argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster, }, }, }, diff --git a/applicationset/controllers/requeue_after_test.go b/applicationset/controllers/requeue_after_test.go index fd922f53566a5..c0c039b88faca 100644 --- a/applicationset/controllers/requeue_after_test.go +++ b/applicationset/controllers/requeue_after_test.go @@ -57,7 +57,7 @@ func TestRequeueAfter(t *testing.T) { }, } fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, duckType) - scmConfig := generators.NewSCMConfig("", []string{""}, true, nil) + scmConfig := generators.NewSCMConfig("", []string{""}, true, nil, true) terminalGenerators := map[string]generators.Generator{ "List": generators.NewListGenerator(), "Clusters": generators.NewClusterGenerator(k8sClient, ctx, appClientset, "argocd"), @@ -100,7 +100,8 @@ func TestRequeueAfter(t *testing.T) { } type args struct { - appset *argov1alpha1.ApplicationSet + appset *argov1alpha1.ApplicationSet + requeueAfterOverride string } tests := []struct { name string @@ -108,11 +109,13 @@ func TestRequeueAfter(t *testing.T) { want time.Duration wantErr assert.ErrorAssertionFunc }{ - {name: "Cluster", args: args{appset: &argov1alpha1.ApplicationSet{ - Spec: argov1alpha1.ApplicationSetSpec{ - Generators: []argov1alpha1.ApplicationSetGenerator{{Clusters: &argov1alpha1.ClusterGenerator{}}}, - }, - }}, want: generators.NoRequeueAfter, wantErr: assert.NoError}, + {name: "Cluster", args: args{ + appset: &argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{{Clusters: &argov1alpha1.ClusterGenerator{}}}, + }, + }, requeueAfterOverride: "", + }, want: generators.NoRequeueAfter, wantErr: assert.NoError}, {name: "ClusterMergeNested", args: args{&argov1alpha1.ApplicationSet{ Spec: argov1alpha1.ApplicationSetSpec{ Generators: []argov1alpha1.ApplicationSetGenerator{ @@ -127,7 +130,7 @@ func TestRequeueAfter(t *testing.T) { }}, }, }, - }}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, + }, ""}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, {name: "ClusterMatrixNested", args: args{&argov1alpha1.ApplicationSet{ Spec: argov1alpha1.ApplicationSetSpec{ Generators: []argov1alpha1.ApplicationSetGenerator{ @@ -142,15 +145,65 @@ func TestRequeueAfter(t *testing.T) { }}, }, }, - }}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, + }, ""}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, {name: "ListGenerator", args: args{appset: &argov1alpha1.ApplicationSet{ Spec: argov1alpha1.ApplicationSetSpec{ Generators: []argov1alpha1.ApplicationSetGenerator{{List: &argov1alpha1.ListGenerator{}}}, }, }}, want: generators.NoRequeueAfter, wantErr: assert.NoError}, + {name: "DuckGenerator", args: args{appset: &argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{{ClusterDecisionResource: &argov1alpha1.DuckTypeGenerator{}}}, + }, + }}, want: generators.DefaultRequeueAfterSeconds, wantErr: assert.NoError}, + {name: "OverrideRequeueDuck", args: args{ + appset: &argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{{ClusterDecisionResource: &argov1alpha1.DuckTypeGenerator{}}}, + }, + }, requeueAfterOverride: "1h", + }, want: 1 * time.Hour, wantErr: assert.NoError}, + {name: "OverrideRequeueGit", args: args{&argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{ + {Git: &argov1alpha1.GitGenerator{}}, + }, + }, + }, "1h"}, want: 1 * time.Hour, wantErr: assert.NoError}, + {name: "OverrideRequeueMatrix", args: args{&argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{ + {Clusters: &argov1alpha1.ClusterGenerator{}}, + {Merge: &argov1alpha1.MergeGenerator{ + Generators: []argov1alpha1.ApplicationSetNestedGenerator{ + { + Clusters: &argov1alpha1.ClusterGenerator{}, + Git: &argov1alpha1.GitGenerator{}, + }, + }, + }}, + }, + }, + }, "5m"}, want: 5 * time.Minute, wantErr: assert.NoError}, + {name: "OverrideRequeueMerge", args: args{&argov1alpha1.ApplicationSet{ + Spec: argov1alpha1.ApplicationSetSpec{ + Generators: []argov1alpha1.ApplicationSetGenerator{ + {Clusters: &argov1alpha1.ClusterGenerator{}}, + {Merge: &argov1alpha1.MergeGenerator{ + Generators: []argov1alpha1.ApplicationSetNestedGenerator{ + { + Clusters: &argov1alpha1.ClusterGenerator{}, + Git: &argov1alpha1.GitGenerator{}, + }, + }, + }}, + }, + }, + }, "12s"}, want: 12 * time.Second, wantErr: assert.NoError}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Setenv("ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER", tt.args.requeueAfterOverride) assert.Equalf(t, tt.want, r.getMinRequeueAfter(tt.args.appset), "getMinRequeueAfter(%v)", tt.args.appset) }) } diff --git a/applicationset/controllers/template/template.go b/applicationset/controllers/template/template.go index bb4bc155d4e59..616b7ef9a7e74 100644 --- a/applicationset/controllers/template/template.go +++ b/applicationset/controllers/template/template.go @@ -69,9 +69,11 @@ func GenerateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.App res = append(res, *app) } } - - logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res)) - logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) + if log.IsLevelEnabled(log.DebugLevel) { + logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) + } else { + logCtx.Infof("generated %d applications", len(res)) + } } return res, applicationSetReason, firstError diff --git a/applicationset/controllers/template/template_test.go b/applicationset/controllers/template/template_test.go index c765e9c1c67a4..27e2c17f10073 100644 --- a/applicationset/controllers/template/template_test.go +++ b/applicationset/controllers/template/template_test.go @@ -2,6 +2,7 @@ package template import ( "fmt" + "maps" "testing" "github.com/stretchr/testify/mock" @@ -18,7 +19,6 @@ import ( rendmock "github.com/argoproj/argo-cd/v2/applicationset/utils/mocks" "github.com/argoproj/argo-cd/v2/pkg/apis/application" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/util/collections" ) func TestGenerateApplications(t *testing.T) { @@ -344,7 +344,7 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { assert.EqualValues(t, cases.expectedApp[0].ObjectMeta.Name, gotApp[0].ObjectMeta.Name) assert.EqualValues(t, cases.expectedApp[0].Spec.Source.TargetRevision, gotApp[0].Spec.Source.TargetRevision) assert.EqualValues(t, cases.expectedApp[0].Spec.Destination.Namespace, gotApp[0].Spec.Destination.Namespace) - assert.True(t, collections.StringMapsEqual(cases.expectedApp[0].ObjectMeta.Labels, gotApp[0].ObjectMeta.Labels)) + assert.True(t, maps.Equal(cases.expectedApp[0].ObjectMeta.Labels, gotApp[0].ObjectMeta.Labels)) }) } } diff --git a/applicationset/generators/cluster.go b/applicationset/generators/cluster.go index eafb3de1fabb6..79765f7bb38e8 100644 --- a/applicationset/generators/cluster.go +++ b/applicationset/generators/cluster.go @@ -15,14 +15,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/argoproj/argo-cd/v2/applicationset/utils" + "github.com/argoproj/argo-cd/v2/common" argoappsetv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) -const ( - ArgoCDSecretTypeLabel = "argocd.argoproj.io/secret-type" - ArgoCDSecretTypeCluster = "cluster" -) - var _ Generator = (*ClusterGenerator)(nil) // ClusterGenerator generates Applications for some or all clusters registered with ArgoCD. @@ -52,7 +48,7 @@ func NewClusterGenerator(c client.Client, ctx context.Context, clientset kuberne // GetRequeueAfter never requeue the cluster generator because the `clusterSecretEventHandler` will requeue the appsets // when the cluster secrets change -func (g *ClusterGenerator) GetRequeueAfter(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) time.Duration { +func (g *ClusterGenerator) GetRequeueAfter(_ *argoappsetv1alpha1.ApplicationSetGenerator) time.Duration { return NoRequeueAfter } @@ -61,6 +57,7 @@ func (g *ClusterGenerator) GetTemplate(appSetGenerator *argoappsetv1alpha1.Appli } func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator, appSet *argoappsetv1alpha1.ApplicationSet, _ client.Client) ([]map[string]interface{}, error) { + logCtx := log.WithField("applicationset", appSet.GetName()).WithField("namespace", appSet.GetNamespace()) if appSetGenerator == nil { return nil, EmptyAppSetGeneratorError } @@ -83,7 +80,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap return nil, nil } - clusterSecrets, err := g.getSecretsByClusterName(appSetGenerator) + clusterSecrets, err := g.getSecretsByClusterName(logCtx, appSetGenerator) if err != nil { return nil, fmt.Errorf("error getting cluster secrets: %w", err) } @@ -92,6 +89,10 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap secretsFound := []corev1.Secret{} + isFlatMode := appSetGenerator.Clusters.FlatList + logCtx.Debugf("Using flat mode = %t for cluster generator", isFlatMode) + clustersParams := make([]map[string]interface{}, 0) + for _, cluster := range clustersFromArgoCD.Items { // If there is a secret for this cluster, then it's a non-local cluster, so it will be // handled by the next step. @@ -103,15 +104,20 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap params["name"] = cluster.Name params["nameNormalized"] = cluster.Name params["server"] = cluster.Server + params["project"] = "" err = appendTemplatedValues(appSetGenerator.Clusters.Values, params, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) if err != nil { return nil, fmt.Errorf("error appending templated values for local cluster: %w", err) } - res = append(res, params) + if isFlatMode { + clustersParams = append(clustersParams, params) + } else { + res = append(res, params) + } - log.WithField("cluster", "local cluster").Info("matched local cluster") + logCtx.WithField("cluster", "local cluster").Info("matched local cluster") } } @@ -123,6 +129,13 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap params["nameNormalized"] = utils.SanitizeName(string(cluster.Data["name"])) params["server"] = string(cluster.Data["server"]) + project, ok := cluster.Data["project"] + if ok { + params["project"] = string(project) + } else { + params["project"] = "" + } + if appSet.Spec.GoTemplate { meta := map[string]interface{}{} @@ -149,19 +162,27 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap return nil, fmt.Errorf("error appending templated values for cluster: %w", err) } - res = append(res, params) + if isFlatMode { + clustersParams = append(clustersParams, params) + } else { + res = append(res, params) + } - log.WithField("cluster", cluster.Name).Info("matched cluster secret") + logCtx.WithField("cluster", cluster.Name).Debug("matched cluster secret") } + if isFlatMode { + res = append(res, map[string]interface{}{ + "clusters": clustersParams, + }) + } return res, nil } -func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) (map[string]corev1.Secret, error) { - // List all Clusters: +func (g *ClusterGenerator) getSecretsByClusterName(log *log.Entry, appSetGenerator *argoappsetv1alpha1.ApplicationSetGenerator) (map[string]corev1.Secret, error) { clusterSecretList := &corev1.SecretList{} - selector := metav1.AddLabelToSelector(&appSetGenerator.Clusters.Selector, ArgoCDSecretTypeLabel, ArgoCDSecretTypeCluster) + selector := metav1.AddLabelToSelector(&appSetGenerator.Clusters.Selector, common.LabelKeySecretType, common.LabelValueSecretTypeCluster) secretSelector, err := metav1.LabelSelectorAsSelector(selector) if err != nil { return nil, fmt.Errorf("error converting label selector: %w", err) @@ -170,7 +191,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1 if err := g.Client.List(context.Background(), clusterSecretList, client.MatchingLabelsSelector{Selector: secretSelector}); err != nil { return nil, err } - log.Debug("clusters matching labels", "count", len(clusterSecretList.Items)) + log.Debugf("clusters matching labels: %d", len(clusterSecretList.Items)) res := map[string]corev1.Secret{} diff --git a/applicationset/generators/cluster_test.go b/applicationset/generators/cluster_test.go index f319081c09218..30d8cf0347b23 100644 --- a/applicationset/generators/cluster_test.go +++ b/applicationset/generators/cluster_test.go @@ -76,18 +76,20 @@ func TestGenerateParams(t *testing.T) { }, }, Data: map[string][]byte{ - "config": []byte("{}"), - "name": []byte("production_01/west"), - "server": []byte("https://production-01.example.com"), + "config": []byte("{}"), + "name": []byte("production_01/west"), + "server": []byte("https://production-01.example.com"), + "project": []byte("prod-project"), }, Type: corev1.SecretType("Opaque"), }, } testCases := []struct { - name string - selector metav1.LabelSelector - values map[string]string - expected []map[string]interface{} + name string + selector metav1.LabelSelector + isFlatMode bool + values map[string]string + expected []map[string]interface{} // clientError is true if a k8s client error should be simulated clientError bool expectedError error @@ -105,17 +107,16 @@ func TestGenerateParams(t *testing.T) { "aaa": "{{ server }}", "no-op": "{{ this-does-not-exist }}", }, expected: []map[string]interface{}{ + {"values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "{{ metadata.annotations.foo.argoproj.io }}", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "{{ metadata.labels.environment }}", "values.aaa": "https://kubernetes.default.svc", "nameNormalized": "in-cluster", "name": "in-cluster", "server": "https://kubernetes.default.svc", "project": ""}, { "values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "production", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "production", "values.aaa": "https://production-01.example.com", "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", }, { "values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "staging", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "staging", "values.aaa": "https://staging-01.example.com", "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", }, - - {"values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "{{ metadata.annotations.foo.argoproj.io }}", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "{{ metadata.labels.environment }}", "values.aaa": "https://kubernetes.default.svc", "nameNormalized": "in-cluster", "name": "in-cluster", "server": "https://kubernetes.default.svc"}, }, clientError: false, expectedError: nil, @@ -131,12 +132,12 @@ func TestGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", }, { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", }, }, clientError: false, @@ -155,7 +156,7 @@ func TestGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "values.foo": "bar", "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", }, }, clientError: false, @@ -181,11 +182,11 @@ func TestGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "values.foo": "bar", "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", }, { "values.foo": "bar", "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", }, }, clientError: false, @@ -214,7 +215,7 @@ func TestGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "values.name": "baz", "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", - "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", }, }, clientError: false, @@ -228,6 +229,74 @@ func TestGenerateParams(t *testing.T) { clientError: true, expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, + { + name: "flat mode without selectors", + selector: metav1.LabelSelector{}, + values: map[string]string{ + "lol1": "lol", + "lol2": "{{values.lol1}}{{values.lol1}}", + "lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", + "foo": "bar", + "bar": "{{ metadata.annotations.foo.argoproj.io }}", + "bat": "{{ metadata.labels.environment }}", + "aaa": "{{ server }}", + "no-op": "{{ this-does-not-exist }}", + }, + expected: []map[string]interface{}{ + { + "clusters": []map[string]interface{}{ + {"values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "{{ metadata.annotations.foo.argoproj.io }}", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "{{ metadata.labels.environment }}", "values.aaa": "https://kubernetes.default.svc", "nameNormalized": "in-cluster", "name": "in-cluster", "server": "https://kubernetes.default.svc", "project": ""}, + { + "values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "production", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "production", "values.aaa": "https://production-01.example.com", "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", + }, + + { + "values.lol1": "lol", "values.lol2": "{{values.lol1}}{{values.lol1}}", "values.lol3": "{{values.lol2}}{{values.lol2}}{{values.lol2}}", "values.foo": "bar", "values.bar": "staging", "values.no-op": "{{ this-does-not-exist }}", "values.bat": "staging", "values.aaa": "https://staging-01.example.com", "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", + }, + }, + }, + }, + isFlatMode: true, + clientError: false, + expectedError: nil, + }, + { + name: "production or staging with flat mode", + selector: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "environment", + Operator: "In", + Values: []string{ + "production", + "staging", + }, + }, + }, + }, + isFlatMode: true, + values: map[string]string{ + "foo": "bar", + }, + expected: []map[string]interface{}{ + { + "clusters": []map[string]interface{}{ + { + "values.foo": "bar", "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", "metadata.labels.environment": "production", "metadata.labels.org": "bar", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "production", "project": "prod-project", + }, + { + "values.foo": "bar", "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", "metadata.labels.environment": "staging", "metadata.labels.org": "foo", + "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "metadata.annotations.foo.argoproj.io": "staging", "project": "", + }, + }, + }, + }, + clientError: false, + expectedError: nil, + }, } // convert []client.Object to []runtime.Object, for use by kubefake package @@ -259,6 +328,7 @@ func TestGenerateParams(t *testing.T) { Clusters: &argoprojiov1alpha1.ClusterGenerator{ Selector: testCase.selector, Values: testCase.values, + FlatList: testCase.isFlatMode, }, }, &applicationSetInfo, nil) @@ -324,10 +394,11 @@ func TestGenerateParamsGoTemplate(t *testing.T) { }, } testCases := []struct { - name string - selector metav1.LabelSelector - values map[string]string - expected []map[string]interface{} + name string + selector metav1.LabelSelector + values map[string]string + isFlatMode bool + expected []map[string]interface{} // clientError is true if a k8s client error should be simulated clientError bool expectedError error @@ -349,6 +420,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -374,6 +446,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -399,6 +472,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "nameNormalized": "in-cluster", "name": "in-cluster", "server": "https://kubernetes.default.svc", + "project": "", "values": map[string]string{ "lol1": "lol", "lol2": "", @@ -427,6 +501,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -442,6 +517,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -472,6 +548,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -512,6 +589,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -530,6 +608,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -573,6 +652,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { "name": "staging-01", "nameNormalized": "staging-01", "server": "https://staging-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "argocd.argoproj.io/secret-type": "cluster", @@ -599,6 +679,162 @@ func TestGenerateParamsGoTemplate(t *testing.T) { clientError: true, expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, + { + name: "Clusters with flat list mode and no selector", + selector: metav1.LabelSelector{}, + isFlatMode: true, + values: map[string]string{ + "lol1": "lol", + "lol2": "{{ .values.lol1 }}{{ .values.lol1 }}", + "lol3": "{{ .values.lol2 }}{{ .values.lol2 }}{{ .values.lol2 }}", + "foo": "bar", + "bar": "{{ if not (empty .metadata) }}{{index .metadata.annotations \"foo.argoproj.io\" }}{{ end }}", + "bat": "{{ if not (empty .metadata) }}{{.metadata.labels.environment}}{{ end }}", + "aaa": "{{ .server }}", + "no-op": "{{ .thisDoesNotExist }}", + }, + expected: []map[string]interface{}{ + { + "clusters": []map[string]interface{}{ + { + "nameNormalized": "in-cluster", + "name": "in-cluster", + "server": "https://kubernetes.default.svc", + "project": "", + "values": map[string]string{ + "lol1": "lol", + "lol2": "", + "lol3": "", + "foo": "bar", + "bar": "", + "bat": "", + "aaa": "https://kubernetes.default.svc", + "no-op": "", + }, + }, + { + "name": "production_01/west", + "nameNormalized": "production-01-west", + "server": "https://production-01.example.com", + "project": "", + "metadata": map[string]interface{}{ + "labels": map[string]string{ + "argocd.argoproj.io/secret-type": "cluster", + "environment": "production", + "org": "bar", + }, + "annotations": map[string]string{ + "foo.argoproj.io": "production", + }, + }, + "values": map[string]string{ + "lol1": "lol", + "lol2": "", + "lol3": "", + "foo": "bar", + "bar": "production", + "bat": "production", + "aaa": "https://production-01.example.com", + "no-op": "", + }, + }, + { + "name": "staging-01", + "nameNormalized": "staging-01", + "server": "https://staging-01.example.com", + "project": "", + "metadata": map[string]interface{}{ + "labels": map[string]string{ + "argocd.argoproj.io/secret-type": "cluster", + "environment": "staging", + "org": "foo", + }, + "annotations": map[string]string{ + "foo.argoproj.io": "staging", + }, + }, + "values": map[string]string{ + "lol1": "lol", + "lol2": "", + "lol3": "", + "foo": "bar", + "bar": "staging", + "bat": "staging", + "aaa": "https://staging-01.example.com", + "no-op": "", + }, + }, + }, + }, + }, + clientError: false, + expectedError: nil, + }, + { + name: "production or staging with flat mode", + selector: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "environment", + Operator: "In", + Values: []string{ + "production", + "staging", + }, + }, + }, + }, + isFlatMode: true, + values: map[string]string{ + "foo": "bar", + }, + expected: []map[string]interface{}{ + { + "clusters": []map[string]interface{}{ + { + "name": "production_01/west", + "nameNormalized": "production-01-west", + "server": "https://production-01.example.com", + "project": "", + "metadata": map[string]interface{}{ + "labels": map[string]string{ + "argocd.argoproj.io/secret-type": "cluster", + "environment": "production", + "org": "bar", + }, + "annotations": map[string]string{ + "foo.argoproj.io": "production", + }, + }, + "values": map[string]string{ + "foo": "bar", + }, + }, + { + "name": "staging-01", + "nameNormalized": "staging-01", + "server": "https://staging-01.example.com", + "project": "", + "metadata": map[string]interface{}{ + "labels": map[string]string{ + "argocd.argoproj.io/secret-type": "cluster", + "environment": "staging", + "org": "foo", + }, + "annotations": map[string]string{ + "foo.argoproj.io": "staging", + }, + }, + "values": map[string]string{ + "foo": "bar", + }, + }, + }, + }, + }, + clientError: false, + expectedError: nil, + }, } // convert []client.Object to []runtime.Object, for use by kubefake package @@ -632,6 +868,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { Clusters: &argoprojiov1alpha1.ClusterGenerator{ Selector: testCase.selector, Values: testCase.values, + FlatList: testCase.isFlatMode, }, }, &applicationSetInfo, nil) diff --git a/applicationset/generators/duck_type.go b/applicationset/generators/duck_type.go index d7ceafd31de3b..7bd78a07146b2 100644 --- a/applicationset/generators/duck_type.go +++ b/applicationset/generators/duck_type.go @@ -52,7 +52,7 @@ func (g *DuckTypeGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1. return time.Duration(*appSetGenerator.ClusterDecisionResource.RequeueAfterSeconds) * time.Second } - return DefaultRequeueAfterSeconds + return getDefaultRequeueAfter() } func (g *DuckTypeGenerator) GetTemplate(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) *argoprojiov1alpha1.ApplicationSetTemplate { diff --git a/applicationset/generators/generator_spec_processor_test.go b/applicationset/generators/generator_spec_processor_test.go index a02ea5e3312c1..2c55fecad5403 100644 --- a/applicationset/generators/generator_spec_processor_test.go +++ b/applicationset/generators/generator_spec_processor_test.go @@ -199,6 +199,7 @@ func TestTransForm(t *testing.T) { "name": "production_01/west", "nameNormalized": "production-01-west", "server": "https://production-01.example.com", + "project": "", }}, }, { @@ -214,6 +215,7 @@ func TestTransForm(t *testing.T) { "name": "some-really-long-server-url", "nameNormalized": "some-really-long-server-url", "server": "https://some-really-long-url-that-will-exceed-63-characters.com", + "project": "", }}, }, } diff --git a/applicationset/generators/git.go b/applicationset/generators/git.go index 74fe02044b473..d119824f40174 100644 --- a/applicationset/generators/git.go +++ b/applicationset/generators/git.go @@ -48,7 +48,7 @@ func (g *GitGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.Appli return time.Duration(*appSetGenerator.Git.RequeueAfterSeconds) * time.Second } - return DefaultRequeueAfterSeconds + return getDefaultRequeueAfter() } func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, appSet *argoprojiov1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { diff --git a/applicationset/generators/interface.go b/applicationset/generators/interface.go index ea105c7842279..88853c73b2b56 100644 --- a/applicationset/generators/interface.go +++ b/applicationset/generators/interface.go @@ -7,6 +7,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/env" ) // Generator defines the interface implemented by all ApplicationSet generators. @@ -30,7 +31,11 @@ var ( NoRequeueAfter time.Duration ) -// DefaultRequeueAfterSeconds is used when GetRequeueAfter is not specified, it is the default time to wait before the next reconcile loop const ( DefaultRequeueAfterSeconds = 3 * time.Minute ) + +func getDefaultRequeueAfter() time.Duration { + // Default is 3 minutes, min is 1 second, max is 1 year + return env.ParseDurationFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER", DefaultRequeueAfterSeconds, 1*time.Second, 8760*time.Hour) +} diff --git a/applicationset/generators/interface_test.go b/applicationset/generators/interface_test.go new file mode 100644 index 0000000000000..d27111bc1453c --- /dev/null +++ b/applicationset/generators/interface_test.go @@ -0,0 +1,29 @@ +package generators + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func Test_getDefaultRequeueAfter(t *testing.T) { + tests := []struct { + name string + requeueAfterEnv string + want time.Duration + }{ + {name: "Default", requeueAfterEnv: "", want: DefaultRequeueAfterSeconds}, + {name: "Min", requeueAfterEnv: "1s", want: 1 * time.Second}, + {name: "Max", requeueAfterEnv: "8760h", want: 8760 * time.Hour}, + {name: "Override", requeueAfterEnv: "10m", want: 10 * time.Minute}, + {name: "LessThanMin", requeueAfterEnv: "1ms", want: DefaultRequeueAfterSeconds}, + {name: "MoreThanMax", requeueAfterEnv: "8761h", want: DefaultRequeueAfterSeconds}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Setenv("ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER", tt.requeueAfterEnv) + assert.Equalf(t, tt.want, getDefaultRequeueAfter(), "getDefaultRequeueAfter()") + }) + } +} diff --git a/applicationset/generators/matrix_test.go b/applicationset/generators/matrix_test.go index 3a961bb0fe877..dec0ab96b45c9 100644 --- a/applicationset/generators/matrix_test.go +++ b/applicationset/generators/matrix_test.go @@ -578,8 +578,8 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { }, }, expected: []map[string]interface{}{ - {"path": "examples/git-generator-files-discovery/cluster-config/dev/config.json", "path.basename": "dev", "path.basenameNormalized": "dev", "name": "dev-01", "nameNormalized": "dev-01", "server": "https://dev-01.example.com", "metadata.labels.environment": "dev", "metadata.labels.argocd.argoproj.io/secret-type": "cluster"}, - {"path": "examples/git-generator-files-discovery/cluster-config/prod/config.json", "path.basename": "prod", "path.basenameNormalized": "prod", "name": "prod-01", "nameNormalized": "prod-01", "server": "https://prod-01.example.com", "metadata.labels.environment": "prod", "metadata.labels.argocd.argoproj.io/secret-type": "cluster"}, + {"path": "examples/git-generator-files-discovery/cluster-config/dev/config.json", "path.basename": "dev", "path.basenameNormalized": "dev", "name": "dev-01", "nameNormalized": "dev-01", "server": "https://dev-01.example.com", "metadata.labels.environment": "dev", "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "project": ""}, + {"path": "examples/git-generator-files-discovery/cluster-config/prod/config.json", "path.basename": "prod", "path.basenameNormalized": "prod", "name": "prod-01", "nameNormalized": "prod-01", "server": "https://prod-01.example.com", "metadata.labels.environment": "prod", "metadata.labels.argocd.argoproj.io/secret-type": "cluster", "project": ""}, }, clientError: false, }, @@ -734,6 +734,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { "name": "dev-01", "nameNormalized": "dev-01", "server": "https://dev-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "environment": "dev", @@ -750,6 +751,7 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { "name": "prod-01", "nameNormalized": "prod-01", "server": "https://prod-01.example.com", + "project": "", "metadata": map[string]interface{}{ "labels": map[string]string{ "environment": "prod", diff --git a/applicationset/generators/merge_test.go b/applicationset/generators/merge_test.go index 005e5c2c32905..ad54debb37dce 100644 --- a/applicationset/generators/merge_test.go +++ b/applicationset/generators/merge_test.go @@ -197,6 +197,7 @@ func TestMergeGenerate(t *testing.T) { } func toAPIExtensionsJSON(t *testing.T, g interface{}) *apiextensionsv1.JSON { + t.Helper() resVal, err := json.Marshal(g) if err != nil { t.Error("unable to unmarshal json", g) diff --git a/applicationset/generators/plugin_test.go b/applicationset/generators/plugin_test.go index 55ebcfd5c7820..0ade708ee569b 100644 --- a/applicationset/generators/plugin_test.go +++ b/applicationset/generators/plugin_test.go @@ -694,7 +694,7 @@ func TestPluginGenerateParams(t *testing.T) { require.NoError(t, err) gotJson, err := json.Marshal(got) require.NoError(t, err) - assert.Equal(t, string(expectedJson), string(gotJson)) + assert.JSONEq(t, string(expectedJson), string(gotJson)) } }) } diff --git a/applicationset/generators/pull_request.go b/applicationset/generators/pull_request.go index 209e09950e581..f0c2bfaacfcf5 100644 --- a/applicationset/generators/pull_request.go +++ b/applicationset/generators/pull_request.go @@ -139,7 +139,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", prErr) } } - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -147,7 +147,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } if generatorConfig.Gitea != nil { providerConfig := generatorConfig.Gitea - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -164,13 +164,13 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } } if providerConfig.BearerToken != nil { - appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) } - return pullrequest.NewBitbucketServiceBearerToken(ctx, providerConfig.API, appToken, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) + return pullrequest.NewBitbucketServiceBearerToken(ctx, appToken, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) } else if providerConfig.BasicAuth != nil { - password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -182,13 +182,13 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera if generatorConfig.Bitbucket != nil { providerConfig := generatorConfig.Bitbucket if providerConfig.BearerToken != nil { - appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) } return pullrequest.NewBitbucketCloudServiceBearerToken(providerConfig.API, appToken, providerConfig.Owner, providerConfig.Repo) } else if providerConfig.BasicAuth != nil { - password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -199,7 +199,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } if generatorConfig.AzureDevOps != nil { providerConfig := generatorConfig.AzureDevOps - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -219,7 +219,7 @@ func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alph } // always default to token, even if not set (public access) - token, err := utils.GetSecretRef(ctx, g.client, cfg.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, cfg.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } diff --git a/applicationset/generators/pull_request_test.go b/applicationset/generators/pull_request_test.go index e02e7312b350f..d4eae1602bfda 100644 --- a/applicationset/generators/pull_request_test.go +++ b/applicationset/generators/pull_request_test.go @@ -283,7 +283,7 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { "gitea.myorg.com", "bitbucket.myorg.com", "azuredevops.myorg.com", - }, true, nil)) + }, true, nil, true)) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -306,7 +306,7 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { } func TestSCMProviderDisabled_PRGenerator(t *testing.T) { - generator := NewPullRequestGenerator(nil, NewSCMConfig("", []string{}, false, nil)) + generator := NewPullRequestGenerator(nil, NewSCMConfig("", []string{}, false, nil, true)) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/applicationset/generators/scm_provider.go b/applicationset/generators/scm_provider.go index 85a2550ae21f9..417b682e50511 100644 --- a/applicationset/generators/scm_provider.go +++ b/applicationset/generators/scm_provider.go @@ -35,14 +35,16 @@ type SCMConfig struct { allowedSCMProviders []string enableSCMProviders bool GitHubApps github_app_auth.Credentials + tokenRefStrictMode bool } -func NewSCMConfig(scmRootCAPath string, allowedSCMProviders []string, enableSCMProviders bool, gitHubApps github_app_auth.Credentials) SCMConfig { +func NewSCMConfig(scmRootCAPath string, allowedSCMProviders []string, enableSCMProviders bool, gitHubApps github_app_auth.Credentials, tokenRefStrictMode bool) SCMConfig { return SCMConfig{ scmRootCAPath: scmRootCAPath, allowedSCMProviders: allowedSCMProviders, enableSCMProviders: enableSCMProviders, GitHubApps: gitHubApps, + tokenRefStrictMode: tokenRefStrictMode, } } @@ -154,7 +156,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError) } } - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Gitlab token: %w", err) } @@ -163,7 +165,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error initializing Gitlab service: %w", err) } } else if providerConfig.Gitea != nil { - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.Gitea.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.Gitea.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Gitea token: %w", err) } @@ -182,13 +184,13 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha } } if providerConfig.BearerToken != nil { - appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) } provider, scmError = scm_provider.NewBitbucketServerProviderBearerToken(ctx, appToken, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts) } else if providerConfig.BasicAuth != nil { - password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -200,7 +202,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error initializing Bitbucket Server service: %w", scmError) } } else if providerConfig.AzureDevOps != nil { - token, err := utils.GetSecretRef(ctx, g.client, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Azure Devops access token: %w", err) } @@ -209,7 +211,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error initializing Azure Devops service: %w", err) } } else if providerConfig.Bitbucket != nil { - appPassword, err := utils.GetSecretRef(ctx, g.client, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace) + appPassword, err := utils.GetSecretRef(ctx, g.client, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Bitbucket cloud appPassword: %w", err) } @@ -283,7 +285,7 @@ func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argop ) } - token, err := utils.GetSecretRef(ctx, g.client, github.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, github.TokenRef, applicationSetInfo.Namespace, g.tokenRefStrictMode) if err != nil { return nil, fmt.Errorf("error fetching Github token: %w", err) } diff --git a/applicationset/metrics/metrics_test.go b/applicationset/metrics/metrics_test.go index b9ed0ae6ec57a..13457ca03d37f 100644 --- a/applicationset/metrics/metrics_test.go +++ b/applicationset/metrics/metrics_test.go @@ -178,7 +178,7 @@ func TestApplicationsetCollector(t *testing.T) { appsetCollector := newAppsetCollector(utils.NewAppsetLister(client), collectedLabels, filter) metrics.Registry.MustRegister(appsetCollector) - req, err := http.NewRequest("GET", "/metrics", nil) + req, err := http.NewRequest(http.MethodGet, "/metrics", nil) require.NoError(t, err) rr := httptest.NewRecorder() handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{}) @@ -220,7 +220,7 @@ func TestObserveReconcile(t *testing.T) { appsetMetrics := NewApplicationsetMetrics(utils.NewAppsetLister(client), collectedLabels, filter) - req, err := http.NewRequest("GET", "/metrics", nil) + req, err := http.NewRequest(http.MethodGet, "/metrics", nil) require.NoError(t, err) rr := httptest.NewRecorder() handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{}) diff --git a/applicationset/services/internal/github_app/client.go b/applicationset/services/internal/github_app/client.go index 742b2bc001383..7cdfd51554bdf 100644 --- a/applicationset/services/internal/github_app/client.go +++ b/applicationset/services/internal/github_app/client.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/bradleyfalzon/ghinstallation/v2" - "github.com/google/go-github/v63/github" + "github.com/google/go-github/v66/github" "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" ) diff --git a/applicationset/services/internal/http/client.go b/applicationset/services/internal/http/client.go index df43d89f873bb..1a4a86285a183 100644 --- a/applicationset/services/internal/http/client.go +++ b/applicationset/services/internal/http/client.go @@ -134,7 +134,7 @@ func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*htt // CheckResponse checks the API response for errors, and returns them if present. func CheckResponse(resp *http.Response) error { - if c := resp.StatusCode; 200 <= c && c <= 299 { + if c := resp.StatusCode; http.StatusOK <= c && c < http.StatusMultipleChoices { return nil } diff --git a/applicationset/services/internal/http/client_test.go b/applicationset/services/internal/http/client_test.go index 9235ce5ab3e7f..29c183b5b2481 100644 --- a/applicationset/services/internal/http/client_test.go +++ b/applicationset/services/internal/http/client_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestClient(t *testing.T) { @@ -24,9 +25,7 @@ func TestClient(t *testing.T) { var clientOptionFns []ClientOptionFunc _, err := NewClient(server.URL, clientOptionFns...) - if err != nil { - t.Fatalf("Failed to create client: %v", err) - } + require.NoError(t, err, "Failed to create client") } func TestClientDo(t *testing.T) { @@ -77,7 +76,7 @@ func TestClientDo(t *testing.T) { "key3": float64(123), }, }, - expectedCode: 200, + expectedCode: http.StatusOK, expectedError: nil, }, { @@ -109,7 +108,7 @@ func TestClientDo(t *testing.T) { })), clientOptionFns: nil, expected: []map[string]interface{}(nil), - expectedCode: 401, + expectedCode: http.StatusUnauthorized, expectedError: fmt.Errorf("API error with status code 401: "), }, } { @@ -118,14 +117,10 @@ func TestClientDo(t *testing.T) { defer cc.fakeServer.Close() client, err := NewClient(cc.fakeServer.URL, cc.clientOptionFns...) - if err != nil { - t.Fatalf("NewClient returned unexpected error: %v", err) - } + require.NoError(t, err, "NewClient returned unexpected error") req, err := client.NewRequest("POST", "", cc.params, nil) - if err != nil { - t.Fatalf("NewRequest returned unexpected error: %v", err) - } + require.NoError(t, err, "NewRequest returned unexpected error") var data []map[string]interface{} @@ -149,12 +144,5 @@ func TestCheckResponse(t *testing.T) { } err := CheckResponse(resp) - if err == nil { - t.Error("Expected an error, got nil") - } - - expected := "API error with status code 400: invalid_request" - if err.Error() != expected { - t.Errorf("Expected error '%s', got '%s'", expected, err.Error()) - } + require.EqualError(t, err, "API error with status code 400: invalid_request") } diff --git a/applicationset/services/plugin/plugin_service_test.go b/applicationset/services/plugin/plugin_service_test.go index 75e7f2c4a095f..c6e795c40371b 100644 --- a/applicationset/services/plugin/plugin_service_test.go +++ b/applicationset/services/plugin/plugin_service_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestPlugin(t *testing.T) { @@ -31,19 +32,13 @@ func TestPlugin(t *testing.T) { defer ts.Close() client, err := NewPluginService(context.Background(), "plugin-test", ts.URL, token, 0) - if err != nil { - t.Errorf("unexpected error: %v", err) - } + require.NoError(t, err) data, err := client.List(context.Background(), nil) - if err != nil { - t.Errorf("unexpected error: %v", err) - } + require.NoError(t, err) var expectedData ServiceResponse err = json.Unmarshal([]byte(expectedJSON), &expectedData) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) assert.Equal(t, &expectedData, data) } diff --git a/applicationset/services/pull_request/bitbucket_cloud.go b/applicationset/services/pull_request/bitbucket_cloud.go index 48083dcb407e3..2ee79d2cfabee 100644 --- a/applicationset/services/pull_request/bitbucket_cloud.go +++ b/applicationset/services/pull_request/bitbucket_cloud.go @@ -19,7 +19,7 @@ type BitbucketCloudPullRequest struct { ID int `json:"id"` Title string `json:"title"` Source BitbucketCloudPullRequestSource `json:"source"` - Author string `json:"author"` + Author BitbucketCloudPullRequestAuthor `json:"author"` } type BitbucketCloudPullRequestSource struct { @@ -35,6 +35,11 @@ type BitbucketCloudPullRequestSourceCommit struct { Hash string `json:"hash"` } +// Also have display_name and uuid, but don't plan to use them. +type BitbucketCloudPullRequestAuthor struct { + Nickname string `json:"nickname"` +} + type PullRequestResponse struct { Page int32 `json:"page"` Size int32 `json:"size"` @@ -134,7 +139,7 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) Title: pull.Title, Branch: pull.Source.Branch.Name, HeadSHA: pull.Source.Commit.Hash, - Author: pull.Author, + Author: pull.Author.Nickname, }) } diff --git a/applicationset/services/pull_request/bitbucket_cloud_test.go b/applicationset/services/pull_request/bitbucket_cloud_test.go index 8d5f7d80ca144..411f6148c85d6 100644 --- a/applicationset/services/pull_request/bitbucket_cloud_test.go +++ b/applicationset/services/pull_request/bitbucket_cloud_test.go @@ -15,6 +15,7 @@ import ( ) func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var err error @@ -37,7 +38,9 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) "hash": "1a8dd249c04a" } }, - "author": "testName" + "author": { + "nickname": "testName" + } } ] }`) @@ -154,7 +157,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "hash": "1a8dd249c04a" } }, - "author": "testName" + "author": { + "nickname": "testName" + } }, { "id": 102, @@ -168,7 +173,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "hash": "4cf807e67a6d" } }, - "author": "testName" + "author": { + "nickname": "testName" + } } ] }`, r.Host)) @@ -191,7 +198,9 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "hash": "6344d9623e3b" } }, - "author": "testName" + "author": { + "nickname": "testName" + } } ] }`, r.Host)) @@ -233,7 +242,7 @@ func TestListPullRequestPaginationCloud(t *testing.T) { func TestListResponseErrorCloud(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(500) + w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") @@ -339,7 +348,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "hash": "1a8dd249c04a" } }, - "author": "testName" + "author": { + "nickname": "testName" + } }, { "id": 200, @@ -353,7 +364,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "hash": "4cf807e67a6d" } }, - "author": "testName" + "author": { + "nickname": "testName" + } } ] }`, r.Host)) @@ -376,7 +389,9 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "hash": "6344d9623e3b" } }, - "author": "testName" + "author": { + "nickname": "testName" + } } ] }`, r.Host)) diff --git a/applicationset/services/pull_request/bitbucket_server_test.go b/applicationset/services/pull_request/bitbucket_server_test.go index 3c9fe1ddd504e..b9da370830fc0 100644 --- a/applicationset/services/pull_request/bitbucket_server_test.go +++ b/applicationset/services/pull_request/bitbucket_server_test.go @@ -16,6 +16,7 @@ import ( ) func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var err error diff --git a/applicationset/services/pull_request/gitea_test.go b/applicationset/services/pull_request/gitea_test.go index fbb0fb15aa4ce..ab58a049e52b1 100644 --- a/applicationset/services/pull_request/gitea_test.go +++ b/applicationset/services/pull_request/gitea_test.go @@ -14,6 +14,7 @@ import ( ) func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") fmt.Println(r.RequestURI) diff --git a/applicationset/services/pull_request/github.go b/applicationset/services/pull_request/github.go index b63f2a9de6a8e..eaee02ffb171d 100644 --- a/applicationset/services/pull_request/github.go +++ b/applicationset/services/pull_request/github.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "github.com/google/go-github/v63/github" + "github.com/google/go-github/v66/github" "golang.org/x/oauth2" ) diff --git a/applicationset/services/pull_request/github_test.go b/applicationset/services/pull_request/github_test.go index 30b908f9fb1b6..fb35ad20b0b99 100644 --- a/applicationset/services/pull_request/github_test.go +++ b/applicationset/services/pull_request/github_test.go @@ -3,8 +3,8 @@ package pull_request import ( "testing" - "github.com/google/go-github/v63/github" - "github.com/stretchr/testify/assert" + "github.com/google/go-github/v66/github" + "github.com/stretchr/testify/require" ) func toPtr(s string) *string { @@ -52,9 +52,8 @@ func TestContainLabels(t *testing.T) { for _, c := range cases { t.Run(c.Name, func(t *testing.T) { - if got := containLabels(c.Labels, c.PullLabels); got != c.Expect { - t.Errorf("expect: %v, got: %v", c.Expect, got) - } + got := containLabels(c.Labels, c.PullLabels) + require.Equal(t, got, c.Expect) }) } } @@ -83,7 +82,7 @@ func TestGetGitHubPRLabelNames(t *testing.T) { for _, test := range Tests { t.Run(test.Name, func(t *testing.T) { labels := getGithubPRLabelNames(test.PullLabels) - assert.Equal(t, test.ExpectedResult, labels) + require.Equal(t, test.ExpectedResult, labels) }) } } diff --git a/applicationset/services/pull_request/gitlab_test.go b/applicationset/services/pull_request/gitlab_test.go index f9e845595e224..18467fe08815d 100644 --- a/applicationset/services/pull_request/gitlab_test.go +++ b/applicationset/services/pull_request/gitlab_test.go @@ -15,14 +15,12 @@ import ( ) func writeMRListResponse(t *testing.T, w io.Writer) { + t.Helper() f, err := os.Open("fixtures/gitlab_mr_list_response.json") - if err != nil { - t.Fatalf("error opening fixture file: %v", err) - } + require.NoErrorf(t, err, "error opening fixture file: %v", err) - if _, err = io.Copy(w, f); err != nil { - t.Fatalf("error writing response: %v", err) - } + _, err = io.Copy(w, f) + require.NoErrorf(t, err, "error writing response: %v", err) } func TestGitLabServiceCustomBaseURL(t *testing.T) { diff --git a/applicationset/services/scm_provider/bitbucket_server.go b/applicationset/services/scm_provider/bitbucket_server.go index 4f723a547059f..79baa727a14b0 100644 --- a/applicationset/services/scm_provider/bitbucket_server.go +++ b/applicationset/services/scm_provider/bitbucket_server.go @@ -129,7 +129,7 @@ func (b *BitbucketServerProvider) RepoHasPath(_ context.Context, repo *Repositor } // No need to query for all pages here response, err := b.client.DefaultApi.GetContent_0(repo.Organization, repo.Repository, path, opts) - if response != nil && response.StatusCode == 404 { + if response != nil && response.StatusCode == http.StatusNotFound { // File/directory not found return false, nil } @@ -203,7 +203,7 @@ func (b *BitbucketServerProvider) getDefaultBranch(org string, repo string) (*bi response, err := b.client.DefaultApi.GetDefaultBranch(org, repo) // The API will return 404 if a default branch is set but doesn't exist. In case the repo is empty and default branch is unset, // we will get an EOF and a nil response. - if (response != nil && response.StatusCode == 404) || (response == nil && err != nil && errors.Is(err, io.EOF)) { + if (response != nil && response.StatusCode == http.StatusNotFound) || (response == nil && err != nil && errors.Is(err, io.EOF)) { return nil, nil } if err != nil { diff --git a/applicationset/services/scm_provider/bitbucket_server_test.go b/applicationset/services/scm_provider/bitbucket_server_test.go index 1d399f8751cbc..5b4a957fea1ab 100644 --- a/applicationset/services/scm_provider/bitbucket_server_test.go +++ b/applicationset/services/scm_provider/bitbucket_server_test.go @@ -14,6 +14,7 @@ import ( ) func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") var err error @@ -82,6 +83,7 @@ func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { } func verifyDefaultRepo(t *testing.T, err error, repos []*Repository) { + t.Helper() require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ diff --git a/applicationset/services/scm_provider/gitea.go b/applicationset/services/scm_provider/gitea.go index 25554d52af85f..500aa0e981334 100644 --- a/applicationset/services/scm_provider/gitea.go +++ b/applicationset/services/scm_provider/gitea.go @@ -128,7 +128,7 @@ func (g *GiteaProvider) ListRepos(ctx context.Context, cloneProtocol string) ([] func (g *GiteaProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) { _, resp, err := g.client.GetContents(repo.Organization, repo.Repository, repo.Branch, path) - if resp != nil && resp.StatusCode == 404 { + if resp != nil && resp.StatusCode == http.StatusNotFound { return false, nil } if fmt.Sprint(err) == "expect file, got directory" { diff --git a/applicationset/services/scm_provider/gitea_test.go b/applicationset/services/scm_provider/gitea_test.go index 231913761014b..1253d30c9a88e 100644 --- a/applicationset/services/scm_provider/gitea_test.go +++ b/applicationset/services/scm_provider/gitea_test.go @@ -15,6 +15,7 @@ import ( ) func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { diff --git a/applicationset/services/scm_provider/github.go b/applicationset/services/scm_provider/github.go index 9d7457c47b990..2e2f2a7faf3d4 100644 --- a/applicationset/services/scm_provider/github.go +++ b/applicationset/services/scm_provider/github.go @@ -6,7 +6,7 @@ import ( "net/http" "os" - "github.com/google/go-github/v63/github" + "github.com/google/go-github/v66/github" "golang.org/x/oauth2" ) @@ -107,7 +107,7 @@ func (g *GithubProvider) RepoHasPath(ctx context.Context, repo *Repository, path Ref: repo.Branch, }) // 404s are not an error here, just a normal false. - if resp != nil && resp.StatusCode == 404 { + if resp != nil && resp.StatusCode == http.StatusNotFound { return false, nil } if err != nil { diff --git a/applicationset/services/scm_provider/github_test.go b/applicationset/services/scm_provider/github_test.go index 03b59c801721a..747f895ab745e 100644 --- a/applicationset/services/scm_provider/github_test.go +++ b/applicationset/services/scm_provider/github_test.go @@ -14,6 +14,7 @@ import ( ) func githubMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { diff --git a/applicationset/services/scm_provider/gitlab_test.go b/applicationset/services/scm_provider/gitlab_test.go index 12f2b8b377a2a..4443086333ccb 100644 --- a/applicationset/services/scm_provider/gitlab_test.go +++ b/applicationset/services/scm_provider/gitlab_test.go @@ -17,6 +17,7 @@ import ( ) func gitlabMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { diff --git a/applicationset/utils/clusterUtils.go b/applicationset/utils/clusterUtils.go index 8c44dc1246be5..b95854e600d2f 100644 --- a/applicationset/utils/clusterUtils.go +++ b/applicationset/utils/clusterUtils.go @@ -2,22 +2,15 @@ package utils import ( "context" - "encoding/json" "fmt" - "strconv" - "strings" "sync" - "time" - - log "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-cd/v2/common" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "k8s.io/utils/ptr" ) // The contents of this file are from @@ -51,9 +44,12 @@ const ( // if we used destination name we infer the server url // if we used both name and server then we return an invalid spec error func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination, clientset kubernetes.Interface, argoCDNamespace string) error { + if dest.IsServerInferred() && dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server) + } if dest.Name != "" { if dest.Server == "" { - server, err := getDestinationServer(ctx, dest.Name, clientset, argoCDNamespace) + server, err := getDestinationBy(ctx, dest.Name, clientset, argoCDNamespace, true) if err != nil { return fmt.Errorf("unable to find destination server: %w", err) } @@ -61,14 +57,25 @@ func ValidateDestination(ctx context.Context, dest *appv1.ApplicationDestination return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name) } dest.SetInferredServer(server) - } else if !dest.IsServerInferred() { + } else if !dest.IsServerInferred() && !dest.IsNameInferred() { return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server) } + } else if dest.Server != "" { + if dest.Name == "" { + serverName, err := getDestinationBy(ctx, dest.Server, clientset, argoCDNamespace, false) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if serverName == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server) + } + dest.SetInferredName(serverName) + } } return nil } -func getDestinationServer(ctx context.Context, clusterName string, clientset kubernetes.Interface, argoCDNamespace string) (string, error) { +func getDestinationBy(ctx context.Context, cluster string, clientset kubernetes.Interface, argoCDNamespace string, byName bool) (string, error) { // settingsMgr := settings.NewSettingsManager(context.TODO(), clientset, namespace) // argoDB := db.NewDB(namespace, settingsMgr, clientset) // clusterList, err := argoDB.ListClusters(ctx) @@ -78,14 +85,17 @@ func getDestinationServer(ctx context.Context, clusterName string, clientset kub } var servers []string for _, c := range clusterList.Items { - if c.Name == clusterName { + if byName && c.Name == cluster { servers = append(servers, c.Server) } + if !byName && c.Server == cluster { + servers = append(servers, c.Name) + } } if len(servers) > 1 { return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers) } else if len(servers) == 0 { - return "", fmt.Errorf("there are no clusters with this name: %s", clusterName) + return "", fmt.Errorf("there are no clusters with this name: %s", cluster) } return servers[0], nil } @@ -109,11 +119,15 @@ func ListClusters(ctx context.Context, clientset kubernetes.Interface, namespace hasInClusterCredentials := false for i, clusterSecret := range clusterSecrets { // This line has changed from the original Argo CD code: now receives an error, and handles it - cluster, err := secretToCluster(&clusterSecret) + cluster, err := db.SecretToCluster(&clusterSecret) if err != nil || cluster == nil { return nil, fmt.Errorf("unable to convert cluster secret to cluster object '%s': %w", clusterSecret.Name, err) } + // db.SecretToCluster populates these, but they're not meant to be available to the caller. + cluster.Labels = nil + cluster.Annotations = nil + clusterList.Items[i] = *cluster if cluster.Server == appv1.KubernetesInternalAPIServerAddr { hasInClusterCredentials = true @@ -150,48 +164,3 @@ func getLocalCluster(clientset kubernetes.Interface) *appv1.Cluster { cluster.ConnectionState.ModifiedAt = &now return cluster } - -// secretToCluster converts a secret into a Cluster object -func secretToCluster(s *corev1.Secret) (*appv1.Cluster, error) { - var config appv1.ClusterConfig - if len(s.Data["config"]) > 0 { - if err := json.Unmarshal(s.Data["config"], &config); err != nil { - // This line has changed from the original Argo CD: now returns an error rather than panicing. - return nil, err - } - } - - var namespaces []string - for _, ns := range strings.Split(string(s.Data["namespaces"]), ",") { - if ns = strings.TrimSpace(ns); ns != "" { - namespaces = append(namespaces, ns) - } - } - var refreshRequestedAt *metav1.Time - if v, found := s.Annotations[appv1.AnnotationKeyRefresh]; found { - requestedAt, err := time.Parse(time.RFC3339, v) - if err != nil { - log.Warnf("Error while parsing date in cluster secret '%s': %v", s.Name, err) - } else { - refreshRequestedAt = &metav1.Time{Time: requestedAt} - } - } - var shard *int64 - if shardStr := s.Data["shard"]; shardStr != nil { - if val, err := strconv.Atoi(string(shardStr)); err != nil { - log.Warnf("Error while parsing shard in cluster secret '%s': %v", s.Name, err) - } else { - shard = ptr.To(int64(val)) - } - } - cluster := appv1.Cluster{ - ID: string(s.UID), - Server: strings.TrimRight(string(s.Data["server"]), "/"), - Name: string(s.Data["name"]), - Namespaces: namespaces, - Config: config, - RefreshRequestedAt: refreshRequestedAt, - Shard: shard, - } - return &cluster, nil -} diff --git a/applicationset/utils/clusterUtils_test.go b/applicationset/utils/clusterUtils_test.go index 9e8694359b6bd..7d71db9f974e1 100644 --- a/applicationset/utils/clusterUtils_test.go +++ b/applicationset/utils/clusterUtils_test.go @@ -20,50 +20,6 @@ const ( fakeNamespace = "fake-ns" ) -// From Argo CD util/db/cluster_test.go -func Test_secretToCluster(t *testing.T) { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "mycluster", - Namespace: fakeNamespace, - }, - Data: map[string][]byte{ - "name": []byte("test"), - "server": []byte("http://mycluster"), - "config": []byte("{\"username\":\"foo\"}"), - }, - } - cluster, err := secretToCluster(secret) - require.NoError(t, err) - assert.Equal(t, argoappv1.Cluster{ - Name: "test", - Server: "http://mycluster", - Config: argoappv1.ClusterConfig{ - Username: "foo", - }, - }, *cluster) -} - -// From Argo CD util/db/cluster_test.go -func Test_secretToCluster_NoConfig(t *testing.T) { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "mycluster", - Namespace: fakeNamespace, - }, - Data: map[string][]byte{ - "name": []byte("test"), - "server": []byte("http://mycluster"), - }, - } - cluster, err := secretToCluster(secret) - require.NoError(t, err) - assert.Equal(t, argoappv1.Cluster{ - Name: "test", - Server: "http://mycluster", - }, *cluster) -} - func createClusterSecret(secretName string, clusterName string, clusterServer string) *corev1.Secret { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -92,7 +48,12 @@ func TestValidateDestination(t *testing.T) { Namespace: "default", } - appCond := ValidateDestination(context.Background(), &dest, nil, fakeNamespace) + secret := createClusterSecret("my-secret", "minikube", "https://127.0.0.1:6443") + objects := []runtime.Object{} + objects = append(objects, secret) + kubeclientset := fake.NewSimpleClientset(objects...) + + appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) require.NoError(t, appCond) assert.False(t, dest.IsServerInferred()) }) diff --git a/applicationset/utils/createOrUpdate_test.go b/applicationset/utils/createOrUpdate_test.go index 2dc5945d2d2cc..de64541337178 100644 --- a/applicationset/utils/createOrUpdate_test.go +++ b/applicationset/utils/createOrUpdate_test.go @@ -229,7 +229,7 @@ spec: require.NoError(t, err) yamlExpected, err := yaml.Marshal(tc.expectedApp) require.NoError(t, err) - assert.Equal(t, string(yamlExpected), string(yamlFound)) + assert.YAMLEq(t, string(yamlExpected), string(yamlFound)) }) } } diff --git a/applicationset/utils/kubernetes.go b/applicationset/utils/kubernetes.go index f9e90bf1d9f81..b5708bad2ab53 100644 --- a/applicationset/utils/kubernetes.go +++ b/applicationset/utils/kubernetes.go @@ -4,14 +4,18 @@ import ( "context" "fmt" + "github.com/argoproj/argo-cd/v2/common" + corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +var ErrDisallowedSecretAccess = fmt.Errorf("secret must have label %q=%q", common.LabelKeySecretType, common.LabelValueSecretTypeSCMCreds) + // getSecretRef gets the value of the key for the specified Secret resource. -func GetSecretRef(ctx context.Context, k8sClient client.Client, ref *argoprojiov1alpha1.SecretRef, namespace string) (string, error) { +func GetSecretRef(ctx context.Context, k8sClient client.Client, ref *argoprojiov1alpha1.SecretRef, namespace string, tokenRefStrictMode bool) (string, error) { if ref == nil { return "", nil } @@ -27,6 +31,11 @@ func GetSecretRef(ctx context.Context, k8sClient client.Client, ref *argoprojiov if err != nil { return "", fmt.Errorf("error fetching secret %s/%s: %w", namespace, ref.SecretName, err) } + + if tokenRefStrictMode && secret.GetLabels()[common.LabelKeySecretType] != common.LabelValueSecretTypeSCMCreds { + return "", fmt.Errorf("secret %s/%s is not a valid SCM creds secret: %w", namespace, ref.SecretName, ErrDisallowedSecretAccess) + } + tokenBytes, ok := secret.Data[ref.Key] if !ok { return "", fmt.Errorf("key %q in secret %s/%s not found", ref.Key, namespace, ref.SecretName) diff --git a/applicationset/utils/kubernetes_test.go b/applicationset/utils/kubernetes_test.go index bddda0c473073..d8e86b89b011c 100644 --- a/applicationset/utils/kubernetes_test.go +++ b/applicationset/utils/kubernetes_test.go @@ -67,7 +67,7 @@ func TestGetSecretRef(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - token, err := GetSecretRef(ctx, client, c.ref, c.namespace) + token, err := GetSecretRef(ctx, client, c.ref, c.namespace, false) if c.hasError { require.Error(t, err) } else { diff --git a/applicationset/utils/map.go b/applicationset/utils/map.go index e15baec29bd9c..0d71f20b50a83 100644 --- a/applicationset/utils/map.go +++ b/applicationset/utils/map.go @@ -8,10 +8,7 @@ func ConvertToMapStringString(mapStringInterface map[string]interface{}) map[str mapStringString := make(map[string]string, len(mapStringInterface)) for key, value := range mapStringInterface { - strKey := fmt.Sprintf("%v", key) - strValue := fmt.Sprintf("%v", value) - - mapStringString[strKey] = strValue + mapStringString[key] = fmt.Sprintf("%v", value) } return mapStringString } diff --git a/applicationset/webhook/webhook.go b/applicationset/webhook/webhook.go index e1c5d63cdb440..5c78001a1deba 100644 --- a/applicationset/webhook/webhook.go +++ b/applicationset/webhook/webhook.go @@ -222,7 +222,7 @@ func getGitGeneratorInfo(payload interface{}) *gitGeneratorInfo { log.Errorf("Failed to parse repoURL '%s'", webURL) return nil } - regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + urlObj.Path[1:] + "(\\.git)?" + regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + urlObj.Hostname() + "(:[0-9]+|)[:/]" + urlObj.Path[1:] + "(\\.git)?$" repoRegexp, err := regexp.Compile(regexpStr) if err != nil { log.Errorf("Failed to compile regexp for repoURL '%s'", webURL) diff --git a/applicationset/webhook/webhook_test.go b/applicationset/webhook/webhook_test.go index 046bbf35f09ab..33a8d134ea76d 100644 --- a/applicationset/webhook/webhook_test.go +++ b/applicationset/webhook/webhook_test.go @@ -199,6 +199,7 @@ func TestWebhookHandler(t *testing.T) { t.Run(test.desc, func(t *testing.T) { fc := fake.NewClientBuilder().WithScheme(scheme).WithObjects( fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), + fakeAppWithGitGenerator("git-github-copy", namespace, "https://github.com/org/repo-copy"), fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab/group/name"), fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"), fakeAppWithGitGeneratorWithRevision("github-shorthand", namespace, "https://github.com/org/repo", "env/dev"), @@ -242,9 +243,8 @@ func TestWebhookHandler(t *testing.T) { for i := range list.Items { gotAppSet := &list.Items[i] if _, isEffected := effectedAppSetsAsExpected[gotAppSet.Name]; isEffected { - if expected, got := test.expectedRefresh, gotAppSet.RefreshRequired(); expected != got { - t.Errorf("unexpected RefreshRequired() for appset '%s' expect: %v got: %v", gotAppSet.Name, expected, got) - } + expected, got := test.expectedRefresh, gotAppSet.RefreshRequired() + require.Equalf(t, expected, got, "unexpected RefreshRequired() for appset '%s' expect: %v got: %v", gotAppSet.Name, expected, got) effectedAppSetsAsExpected[gotAppSet.Name] = true } else { assert.False(t, gotAppSet.RefreshRequired()) diff --git a/assets/builtin-policy.csv b/assets/builtin-policy.csv index 81c8ca5092cb4..28f565260d88d 100644 --- a/assets/builtin-policy.csv +++ b/assets/builtin-policy.csv @@ -10,6 +10,7 @@ p, role:readonly, applications, get, */*, allow p, role:readonly, certificates, get, *, allow p, role:readonly, clusters, get, *, allow p, role:readonly, repositories, get, *, allow +p, role:readonly, write-repositories, get, *, allow p, role:readonly, projects, get, *, allow p, role:readonly, accounts, get, *, allow p, role:readonly, gpgkeys, get, *, allow @@ -34,6 +35,9 @@ p, role:admin, clusters, delete, *, allow p, role:admin, repositories, create, *, allow p, role:admin, repositories, update, *, allow p, role:admin, repositories, delete, *, allow +p, role:admin, write-repositories, create, *, allow +p, role:admin, write-repositories, update, *, allow +p, role:admin, write-repositories, delete, *, allow p, role:admin, projects, create, *, allow p, role:admin, projects, update, *, allow p, role:admin, projects, delete, *, allow diff --git a/assets/swagger.json b/assets/swagger.json index 1e8a981c51c66..db3072e5a7bc6 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -4084,6 +4084,504 @@ } } }, + "/api/v1/write-repocreds": { + "get": { + "tags": [ + "RepoCredsService" + ], + "summary": "ListWriteRepositoryCredentials gets a list of all configured repository credential sets that have write access", + "operationId": "RepoCredsService_ListWriteRepositoryCredentials", + "parameters": [ + { + "type": "string", + "description": "Repo URL for query.", + "name": "url", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RepoCredsList" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + }, + "post": { + "tags": [ + "RepoCredsService" + ], + "summary": "CreateWriteRepositoryCredentials creates a new repository credential set with write access", + "operationId": "RepoCredsService_CreateWriteRepositoryCredentials", + "parameters": [ + { + "description": "Repository definition", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1RepoCreds" + } + }, + { + "type": "boolean", + "description": "Whether to create in upsert mode.", + "name": "upsert", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RepoCreds" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repocreds/{creds.url}": { + "put": { + "tags": [ + "RepoCredsService" + ], + "summary": "UpdateWriteRepositoryCredentials updates a repository credential set with write access", + "operationId": "RepoCredsService_UpdateWriteRepositoryCredentials", + "parameters": [ + { + "type": "string", + "description": "URL is the URL to which these credentials match", + "name": "creds.url", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1RepoCreds" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RepoCreds" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repocreds/{url}": { + "delete": { + "tags": [ + "RepoCredsService" + ], + "summary": "DeleteWriteRepositoryCredentials deletes a repository credential set with write access from the configuration", + "operationId": "RepoCredsService_DeleteWriteRepositoryCredentials", + "parameters": [ + { + "type": "string", + "name": "url", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/repocredsRepoCredsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repositories": { + "get": { + "tags": [ + "RepositoryService" + ], + "summary": "ListWriteRepositories gets a list of all configured write repositories", + "operationId": "RepositoryService_ListWriteRepositories", + "parameters": [ + { + "type": "string", + "description": "Repo URL for query.", + "name": "repo", + "in": "query" + }, + { + "type": "boolean", + "description": "Whether to force a cache refresh on repo's connection state.", + "name": "forceRefresh", + "in": "query" + }, + { + "type": "string", + "description": "App project for query.", + "name": "appProject", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryList" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + }, + "post": { + "tags": [ + "RepositoryService" + ], + "summary": "CreateWriteRepository creates a new write repository configuration", + "operationId": "RepositoryService_CreateWriteRepository", + "parameters": [ + { + "description": "Repository definition", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + }, + { + "type": "boolean", + "description": "Whether to create in upsert mode.", + "name": "upsert", + "in": "query" + }, + { + "type": "boolean", + "description": "Whether to operate on credential set instead of repository.", + "name": "credsOnly", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repositories/{repo.repo}": { + "put": { + "tags": [ + "RepositoryService" + ], + "summary": "UpdateWriteRepository updates a write repository configuration", + "operationId": "RepositoryService_UpdateWriteRepository", + "parameters": [ + { + "type": "string", + "description": "Repo contains the URL to the remote repository", + "name": "repo.repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repositories/{repo}": { + "get": { + "tags": [ + "RepositoryService" + ], + "summary": "GetWrite returns a repository or its write credentials", + "operationId": "RepositoryService_GetWrite", + "parameters": [ + { + "type": "string", + "description": "Repo URL for query", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Whether to force a cache refresh on repo's connection state.", + "name": "forceRefresh", + "in": "query" + }, + { + "type": "string", + "description": "App project for query.", + "name": "appProject", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + }, + "delete": { + "tags": [ + "RepositoryService" + ], + "summary": "DeleteWriteRepository deletes a write repository from the configuration", + "operationId": "RepositoryService_DeleteWriteRepository", + "parameters": [ + { + "type": "string", + "description": "Repo URL for query", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Whether to force a cache refresh on repo's connection state.", + "name": "forceRefresh", + "in": "query" + }, + { + "type": "string", + "description": "App project for query.", + "name": "appProject", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/repositoryRepoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/api/v1/write-repositories/{repo}/validate": { + "post": { + "tags": [ + "RepositoryService" + ], + "summary": "ValidateWriteAccess validates write access to a repository with given parameters", + "operationId": "RepositoryService_ValidateWriteAccess", + "parameters": [ + { + "type": "string", + "description": "The URL to the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "description": "The URL to the repo", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + }, + { + "type": "string", + "description": "Username for accessing repo.", + "name": "username", + "in": "query" + }, + { + "type": "string", + "description": "Password for accessing repo.", + "name": "password", + "in": "query" + }, + { + "type": "string", + "description": "Private key data for accessing SSH repository.", + "name": "sshPrivateKey", + "in": "query" + }, + { + "type": "boolean", + "description": "Whether to skip certificate or host key validation.", + "name": "insecure", + "in": "query" + }, + { + "type": "string", + "description": "TLS client cert data for accessing HTTPS repository.", + "name": "tlsClientCertData", + "in": "query" + }, + { + "type": "string", + "description": "TLS client cert key for accessing HTTPS repository.", + "name": "tlsClientCertKey", + "in": "query" + }, + { + "type": "string", + "description": "The type of the repo.", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "The name of the repo.", + "name": "name", + "in": "query" + }, + { + "type": "boolean", + "description": "Whether helm-oci support should be enabled for this repo.", + "name": "enableOci", + "in": "query" + }, + { + "type": "string", + "description": "Github App Private Key PEM data.", + "name": "githubAppPrivateKey", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "Github App ID of the app used to access the repo.", + "name": "githubAppID", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "Github App Installation ID of the installed GitHub App.", + "name": "githubAppInstallationID", + "in": "query" + }, + { + "type": "string", + "description": "Github App Enterprise base url if empty will default to https://api.github.com.", + "name": "githubAppEnterpriseBaseUrl", + "in": "query" + }, + { + "type": "string", + "description": "HTTP/HTTPS proxy to access the repository.", + "name": "proxy", + "in": "query" + }, + { + "type": "string", + "description": "Reference between project and repository that allow you automatically to be added as item inside SourceRepos project entity.", + "name": "project", + "in": "query" + }, + { + "type": "string", + "description": "Google Cloud Platform service account key.", + "name": "gcpServiceAccountKey", + "in": "query" + }, + { + "type": "boolean", + "description": "Whether to force HTTP basic auth.", + "name": "forceHttpBasicAuth", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/repositoryRepoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, "/api/version": { "get": { "tags": [ @@ -4557,6 +5055,9 @@ "namespace": { "type": "string" }, + "requiresDeletionConfirmation": { + "type": "boolean" + }, "requiresPruning": { "type": "boolean" }, @@ -4688,6 +5189,12 @@ "clusterSettings": { "type": "object", "properties": { + "additionalUrls": { + "type": "array", + "items": { + "type": "string" + } + }, "appLabelKey": { "type": "string" }, @@ -4716,9 +5223,15 @@ "help": { "$ref": "#/definitions/clusterHelp" }, + "hydratorEnabled": { + "type": "boolean" + }, "impersonationEnabled": { "type": "boolean" }, + "installationID": { + "type": "string" + }, "kustomizeOptions": { "$ref": "#/definitions/v1alpha1KustomizeOptions" }, @@ -6084,7 +6597,7 @@ "properties": { "defaultServiceAccount": { "type": "string", - "title": "ServiceAccountName to be used for impersonation during the sync operation" + "title": "DefaultServiceAccount to be used for impersonation during the sync operation" }, "namespace": { "description": "Namespace specifies the target namespace for the application's resources.", @@ -6523,6 +7036,10 @@ "kustomize": { "$ref": "#/definitions/v1alpha1ApplicationSourceKustomize" }, + "name": { + "description": "Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications.", + "type": "string" + }, "path": { "description": "Path is a directory path within the Git repository, and is only valid for applications sourced from Git.", "type": "string" @@ -6614,6 +7131,14 @@ "type": "boolean", "title": "SkipCrds skips custom resource definition installation step (Helm's --skip-crds)" }, + "skipSchemaValidation": { + "type": "boolean", + "title": "SkipSchemaValidation skips JSON schema validation (Helm's --skip-schema-validation)" + }, + "skipTests": { + "description": "SkipTests skips test manifest installation step (Helm's --skip-tests).", + "type": "boolean" + }, "valueFiles": { "type": "array", "title": "ValuesFiles is a list of Helm value files to use when generating a template", @@ -6833,6 +7358,9 @@ "source": { "$ref": "#/definitions/v1alpha1ApplicationSource" }, + "sourceHydrator": { + "$ref": "#/definitions/v1alpha1SourceHydrator" + }, "sources": { "type": "array", "title": "Sources is a reference to the location of the application's manifests or chart", @@ -6890,6 +7418,9 @@ "$ref": "#/definitions/applicationv1alpha1ResourceStatus" } }, + "sourceHydrator": { + "$ref": "#/definitions/v1alpha1SourceHydratorStatus" + }, "sourceType": { "type": "string", "title": "SourceType specifies the type of this application" @@ -7137,12 +7668,20 @@ "description": "Server requires Bearer authentication. This client will not attempt to use\nrefresh tokens for an OAuth2 flow.\nTODO: demonstrate an OAuth2 compatible client.", "type": "string" }, + "disableCompression": { + "description": "DisableCompression bypasses automatic GZip compression requests to the server.", + "type": "boolean" + }, "execProviderConfig": { "$ref": "#/definitions/v1alpha1ExecProviderConfig" }, "password": { "type": "string" }, + "proxyUrl": { + "type": "string", + "title": "ProxyURL is the URL to the proxy to be used for all requests send to the server" + }, "tlsClientConfig": { "$ref": "#/definitions/v1alpha1TLSClientConfig" }, @@ -7156,6 +7695,10 @@ "description": "ClusterGenerator defines a generator to match against clusters registered with ArgoCD.", "type": "object", "properties": { + "flatList": { + "type": "boolean", + "title": "returns the clusters a single 'clusters' value in the template" + }, "selector": { "$ref": "#/definitions/v1LabelSelector" }, @@ -7305,6 +7848,24 @@ } } }, + "v1alpha1DrySource": { + "description": "DrySource specifies a location for dry \"don't repeat yourself\" manifest source information.", + "type": "object", + "properties": { + "path": { + "type": "string", + "title": "Path is a directory path within the Git repository where the manifests are located" + }, + "repoURL": { + "type": "string", + "title": "RepoURL is the URL to the git repository that contains the application manifests" + }, + "targetRevision": { + "type": "string", + "title": "TargetRevision defines the revision of the source to hydrate" + } + } + }, "v1alpha1DuckTypeGenerator": { "description": "DuckType defines a generator to match against clusters registered with ArgoCD.", "type": "object", @@ -7475,6 +8036,9 @@ "type": "object", "title": "HealthStatus contains information about the currently observed health state of an application or resource", "properties": { + "lastTransitionTime": { + "$ref": "#/definitions/v1Time" + }, "message": { "type": "string", "title": "Message is a human-readable informational message describing the health status" @@ -7556,6 +8120,47 @@ } } }, + "v1alpha1HydrateOperation": { + "type": "object", + "title": "HydrateOperation contains information about the most recent hydrate operation", + "properties": { + "drySHA": { + "type": "string", + "title": "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation" + }, + "finishedAt": { + "$ref": "#/definitions/v1Time" + }, + "hydratedSHA": { + "type": "string", + "title": "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation" + }, + "message": { + "type": "string", + "title": "Message contains a message describing the current status of the hydrate operation" + }, + "phase": { + "type": "string", + "title": "Phase indicates the status of the hydrate operation" + }, + "sourceHydrator": { + "$ref": "#/definitions/v1alpha1SourceHydrator" + }, + "startedAt": { + "$ref": "#/definitions/v1Time" + } + } + }, + "v1alpha1HydrateTo": { + "description": "HydrateTo specifies a location to which hydrated manifests should be pushed as a \"staging area\" before being moved to\nthe SyncSource. The RepoURL and Path are assumed based on the associated SyncSource config in the SourceHydrator.", + "type": "object", + "properties": { + "targetBranch": { + "type": "string", + "title": "TargetBranch is the branch to which hydrated manifests should be committed" + } + } + }, "v1alpha1Info": { "type": "object", "properties": { @@ -9163,10 +9768,59 @@ } } }, + "v1alpha1SourceHydrator": { + "description": "SourceHydrator specifies a dry \"don't repeat yourself\" source for manifests, a sync source from which to sync\nhydrated manifests, and an optional hydrateTo location to act as a \"staging\" aread for hydrated manifests.", + "type": "object", + "properties": { + "drySource": { + "$ref": "#/definitions/v1alpha1DrySource" + }, + "hydrateTo": { + "$ref": "#/definitions/v1alpha1HydrateTo" + }, + "syncSource": { + "$ref": "#/definitions/v1alpha1SyncSource" + } + } + }, + "v1alpha1SourceHydratorStatus": { + "type": "object", + "title": "SourceHydratorStatus contains information about the current state of source hydration", + "properties": { + "currentOperation": { + "$ref": "#/definitions/v1alpha1HydrateOperation" + }, + "lastSuccessfulOperation": { + "$ref": "#/definitions/v1alpha1SuccessfulHydrateOperation" + } + } + }, + "v1alpha1SuccessfulHydrateOperation": { + "type": "object", + "title": "SuccessfulHydrateOperation contains information about the most recent successful hydrate operation", + "properties": { + "drySHA": { + "type": "string", + "title": "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation" + }, + "hydratedSHA": { + "type": "string", + "title": "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation" + }, + "sourceHydrator": { + "$ref": "#/definitions/v1alpha1SourceHydrator" + } + } + }, "v1alpha1SyncOperation": { "description": "SyncOperation contains details about a sync operation.", "type": "object", "properties": { + "autoHealAttemptsCount": { + "type": "integer", + "format": "int64", + "title": "SelfHealAttemptsCount contains the number of auto-heal attempts" + }, "dryRun": { "type": "boolean", "title": "DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync" @@ -9317,6 +9971,20 @@ } } }, + "v1alpha1SyncSource": { + "description": "SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the\nassociated DrySource config in the SourceHydrator.", + "type": "object", + "properties": { + "path": { + "description": "Path is a directory path within the git repository where hydrated manifests should be committed to and synced\nfrom. If hydrateTo is set, this is just the path from which hydrated manifests will be synced.", + "type": "string" + }, + "targetBranch": { + "type": "string", + "title": "TargetBranch is the branch to which hydrated manifests should be committed" + } + } + }, "v1alpha1SyncStatus": { "type": "object", "title": "SyncStatus contains information about the currently observed live and desired states of an application", diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 95dc64466ccef..83ddabe82b3ef 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -6,6 +6,7 @@ import ( "math" "os" "os/signal" + "runtime/debug" "syscall" "time" @@ -13,10 +14,12 @@ import ( "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/controller" "github.com/argoproj/argo-cd/v2/controller/sharding" @@ -56,7 +59,12 @@ func NewCommand() *cobra.Command { repoErrorGracePeriod int64 repoServerAddress string repoServerTimeoutSeconds int + commitServerAddress string selfHealTimeoutSeconds int + selfHealBackoffTimeoutSeconds int + selfHealBackoffFactor int + selfHealBackoffCapSeconds int + syncTimeout int statusProcessors int operationProcessors int glogLevel int @@ -81,7 +89,8 @@ func NewCommand() *cobra.Command { ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts // argocd k8s event logging flag - enableK8sEvent []string + enableK8sEvent []string + hydratorEnabled bool ) command := cobra.Command{ Use: cliName, @@ -106,6 +115,13 @@ func NewCommand() *cobra.Command { cli.SetLogLevel(cmdutil.LogLevel) cli.SetGLogLevel(glogLevel) + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + config, err := clientConfig.ClientConfig() errors.CheckError(err) errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) @@ -144,6 +160,8 @@ func NewCommand() *cobra.Command { repoClientset := apiclient.NewRepoServerClientset(repoServerAddress, repoServerTimeoutSeconds, tlsConfig) + commitClientset := commitclient.NewCommitServerClientset(commitServerAddress) + cache, err := cacheSource() errors.CheckError(err) cache.Cache.SetClient(cacheutil.NewTwoLevelClient(cache.Cache.GetClient(), 10*time.Minute)) @@ -156,18 +174,29 @@ func NewCommand() *cobra.Command { kubectl := kubeutil.NewKubectl() clusterSharding, err := sharding.GetClusterSharding(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) errors.CheckError(err) + var selfHealBackoff *wait.Backoff + if selfHealBackoffTimeoutSeconds != 0 { + selfHealBackoff = &wait.Backoff{ + Duration: time.Duration(selfHealBackoffTimeoutSeconds) * time.Second, + Factor: float64(selfHealBackoffFactor), + Cap: time.Duration(selfHealBackoffCapSeconds) * time.Second, + } + } appController, err = controller.NewApplicationController( namespace, settingsMgr, kubeClient, appClient, repoClientset, + commitClientset, cache, kubectl, resyncDuration, hardResyncDuration, time.Duration(appResyncJitter)*time.Second, time.Duration(selfHealTimeoutSeconds)*time.Second, + selfHealBackoff, + time.Duration(syncTimeout)*time.Second, time.Duration(repoErrorGracePeriod)*time.Second, metricsPort, metricsCacheExpiration, @@ -182,9 +211,10 @@ func NewCommand() *cobra.Command { enableDynamicClusterDistribution, ignoreNormalizerOpts, enableK8sEvent, + hydratorEnabled, ) errors.CheckError(err) - cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) + cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer(), nil) stats.RegisterStackDumper() stats.StartStatsTicker(10 * time.Minute) @@ -224,6 +254,7 @@ func NewCommand() *cobra.Command { command.Flags().Int64Var(&repoErrorGracePeriod, "repo-error-grace-period-seconds", int64(env.ParseDurationFromEnv("ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Grace period in seconds for ignoring consecutive errors while communicating with repo server.") command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address.") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") + command.Flags().StringVar(&commitServerAddress, "commit-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER", common.DefaultCommitServerAddr), "Commit server address.") command.Flags().IntVar(&statusProcessors, "status-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS", 20, 0, math.MaxInt32), "Number of application status processors") command.Flags().IntVar(&operationProcessors, "operation-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS", 10, 0, math.MaxInt32), "Number of application operation processors") command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") @@ -231,7 +262,11 @@ func NewCommand() *cobra.Command { command.Flags().IntVar(&glogLevel, "gloglevel", 0, "Set the glog logging level") command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortArgoCDMetrics, "Start metrics server on given port") command.Flags().DurationVar(&metricsCacheExpiration, "metrics-cache-expiration", env.ParseDurationFromEnv("ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION", 0*time.Second, 0, math.MaxInt64), "Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s)") - command.Flags().IntVar(&selfHealTimeoutSeconds, "self-heal-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS", 5, 0, math.MaxInt32), "Specifies timeout between application self heal attempts") + command.Flags().IntVar(&selfHealTimeoutSeconds, "self-heal-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS", 0, 0, math.MaxInt32), "Specifies timeout between application self heal attempts") + command.Flags().IntVar(&selfHealBackoffTimeoutSeconds, "self-heal-backoff-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS", 2, 0, math.MaxInt32), "Specifies initial timeout of exponential backoff between self heal attempts") + command.Flags().IntVar(&selfHealBackoffFactor, "self-heal-backoff-factor", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR", 3, 0, math.MaxInt32), "Specifies factor of exponential timeout between application self heal attempts") + command.Flags().IntVar(&selfHealBackoffCapSeconds, "self-heal-backoff-cap-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS", 300, 0, math.MaxInt32), "Specifies max timeout of exponential backoff between application self heal attempts") + command.Flags().IntVar(&syncTimeout, "sync-timeout", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT", 0, 0, math.MaxInt32), "Specifies the timeout after which a sync would be terminated. 0 means no timeout (default 0).") command.Flags().Int64Var(&kubectlParallelismLimit, "kubectl-parallelism-limit", env.ParseInt64FromEnv("ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT", 20, 0, math.MaxInt64), "Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit.") command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server") command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server") @@ -258,7 +293,7 @@ func NewCommand() *cobra.Command { command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout-seconds", env.ParseDurationFromEnv("ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT", 0*time.Second, 0, math.MaxInt64), "Set ignore normalizer JQ execution timeout") // argocd k8s event logging flag command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)") - + command.Flags().BoolVar(&hydratorEnabled, "hydrator-enabled", env.ParseBoolFromEnv("ARGOCD_HYDRATOR_ENABLED", false), "Feature flag to enable Hydrator. Default (\"false\")") cacheSource = appstatecache.AddCacheFlagsToCmd(&command, cacheutil.Options{ OnClientCreated: func(client *redis.Client) { redisClient = client diff --git a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go index d2f4ce36d98cf..ce7b69c69b565 100644 --- a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go +++ b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go @@ -5,6 +5,7 @@ import ( "math" "net/http" "os" + "runtime/debug" "time" "github.com/argoproj/pkg/stats" @@ -38,7 +39,6 @@ import ( appsetmetrics "github.com/argoproj/argo-cd/v2/applicationset/metrics" "github.com/argoproj/argo-cd/v2/applicationset/services" appv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/argo-cd/v2/util/errors" @@ -73,6 +73,7 @@ func NewCommand() *cobra.Command { metricsAplicationsetLabels []string enableScmProviders bool webhookParallelism int + tokenRefStrictMode bool ) scheme := runtime.NewScheme() _ = clientgoscheme.AddToScheme(scheme) @@ -100,6 +101,13 @@ func NewCommand() *cobra.Command { ctrl.SetLogger(logutils.NewLogrusLogger(logutils.NewWithCurrentConfig())) + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + restConfig, err := clientConfig.ClientConfig() errors.CheckError(err) @@ -162,10 +170,9 @@ func NewCommand() *cobra.Command { errors.CheckError(err) argoSettingsMgr := argosettings.NewSettingsManager(ctx, k8sClient, namespace) - appSetConfig := appclientset.NewForConfigOrDie(mgr.GetConfig()) argoCDDB := db.NewDB(namespace, argoSettingsMgr, k8sClient) - scmConfig := generators.NewSCMConfig(scmRootCAPath, allowedScmProviders, enableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB))) + scmConfig := generators.NewSCMConfig(scmRootCAPath, allowedScmProviders, enableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB)), tokenRefStrictMode) tlsConfig := apiclient.TLSConfiguration{ DisableTLS: repoServerPlaintext, @@ -211,7 +218,6 @@ func NewCommand() *cobra.Command { Renderer: &utils.Render{}, Policy: policyObj, EnablePolicyOverride: enablePolicyOverride, - ArgoAppClientset: appSetConfig, KubeClientset: k8sClient, ArgoDB: argoCDDB, ArgoCDNamespace: namespace, @@ -252,6 +258,7 @@ func NewCommand() *cobra.Command { command.Flags().StringSliceVar(&allowedScmProviders, "allowed-scm-providers", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS", []string{}, ","), "The list of allowed custom SCM provider API URLs. This restriction does not apply to SCM or PR generators which do not accept a custom API URL. (Default: Empty = all)") command.Flags().BoolVar(&enableScmProviders, "enable-scm-providers", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS", true), "Enable retrieving information from SCM providers, used by the SCM and PR generators (Default: true)") command.Flags().BoolVar(&dryRun, "dry-run", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN", false), "Enable dry run mode") + command.Flags().BoolVar(&tokenRefStrictMode, "token-ref-strict-mode", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE", false), fmt.Sprintf("Set to true to require secrets referenced by SCM providers to have the %s=%s label set (Default: false)", common.LabelKeySecretType, common.LabelValueSecretTypeSCMCreds)) command.Flags().BoolVar(&enableProgressiveSyncs, "enable-progressive-syncs", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS", false), "Enable use of the experimental progressive syncs feature.") command.Flags().BoolVar(&enableNewGitFileGlobbing, "enable-new-git-file-globbing", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING", false), "Enable new globbing in Git files generator.") command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server") diff --git a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go index 197f52e01ade7..9d1894695f5af 100644 --- a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go +++ b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go @@ -1,6 +1,7 @@ package commands import ( + "runtime/debug" "time" "github.com/argoproj/pkg/stats" @@ -44,6 +45,13 @@ func NewCommand() *cobra.Command { cli.SetLogFormat(cmdutil.LogFormat) cli.SetLogLevel(cmdutil.LogLevel) + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + config, err := plugin.ReadPluginConfig(configFilePath) errors.CheckError(err) diff --git a/cmd/argocd-commit-server/commands/argocd_commit_server.go b/cmd/argocd-commit-server/commands/argocd_commit_server.go new file mode 100644 index 0000000000000..5c07bc0c1469c --- /dev/null +++ b/cmd/argocd-commit-server/commands/argocd_commit_server.go @@ -0,0 +1,117 @@ +package commands + +import ( + "fmt" + "net" + "net/http" + "os" + "os/signal" + "sync" + "syscall" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "google.golang.org/grpc/health/grpc_health_v1" + + cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" + "github.com/argoproj/argo-cd/v2/commitserver" + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util/askpass" + "github.com/argoproj/argo-cd/v2/util/cli" + "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/healthz" + ioutil "github.com/argoproj/argo-cd/v2/util/io" +) + +// NewCommand returns a new instance of an argocd-commit-server command +func NewCommand() *cobra.Command { + var ( + listenHost string + listenPort int + metricsPort int + metricsHost string + ) + command := &cobra.Command{ + Use: "argocd-commit-server", + Short: "Run Argo CD Commit Server", + Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.", + RunE: func(cmd *cobra.Command, args []string) error { + vers := common.GetVersion() + vers.LogStartupInfo( + "Argo CD Commit Server", + map[string]any{ + "port": listenPort, + }, + ) + + cli.SetLogFormat(cmdutil.LogFormat) + cli.SetLogLevel(cmdutil.LogLevel) + + metricsServer := metrics.NewMetricsServer() + http.Handle("/metrics", metricsServer.GetHandler()) + go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }() + + askPassServer := askpass.NewServer(askpass.CommitServerSocketPath) + go func() { errors.CheckError(askPassServer.Run()) }() + + server := commitserver.NewServer(askPassServer, metricsServer) + grpc := server.CreateGRPC() + + listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", listenHost, listenPort)) + errors.CheckError(err) + + healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error { + if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" { + // connect to itself to make sure commit server is able to serve connection + // used by liveness probe to auto restart commit server + conn, err := apiclient.NewConnection(fmt.Sprintf("localhost:%d", listenPort)) + if err != nil { + return err + } + defer ioutil.Close(conn) + client := grpc_health_v1.NewHealthClient(conn) + res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{}) + if err != nil { + return err + } + if res.Status != grpc_health_v1.HealthCheckResponse_SERVING { + return fmt.Errorf("grpc health check status is '%v'", res.Status) + } + return nil + } + return nil + }) + + // Graceful shutdown code adapted from here: https://gist.github.com/embano1/e0bf49d24f1cdd07cffad93097c04f0a + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + s := <-sigCh + log.Printf("got signal %v, attempting graceful shutdown", s) + grpc.GracefulStop() + wg.Done() + }() + + log.Println("starting grpc server") + err = grpc.Serve(listener) + errors.CheckError(err) + wg.Wait() + log.Println("clean shutdown") + + return nil + }, + } + command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "text"), "Set the logging format. One of: text|json") + command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error") + command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS", common.DefaultAddressCommitServer), "Listen on given address for incoming connections") + command.Flags().IntVar(&listenPort, "port", common.DefaultPortCommitServer, "Listen on given port for incoming connections") + command.Flags().StringVar(&metricsHost, "metrics-address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS", common.DefaultAddressCommitServerMetrics), "Listen on given address for metrics") + command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortCommitServerMetrics, "Start metrics server on given port") + + return command +} diff --git a/cmd/argocd-dex/commands/argocd_dex.go b/cmd/argocd-dex/commands/argocd_dex.go index 43efbbb050dd5..f674266738944 100644 --- a/cmd/argocd-dex/commands/argocd_dex.go +++ b/cmd/argocd-dex/commands/argocd_dex.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "runtime/debug" "syscall" "github.com/argoproj/argo-cd/v2/common" @@ -66,6 +67,14 @@ func NewRunDexCommand() *cobra.Command { cli.SetLogFormat(cmdutil.LogFormat) cli.SetLogLevel(cmdutil.LogLevel) + + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + _, err = exec.LookPath("dex") errors.CheckError(err) config, err := clientConfig.ClientConfig() diff --git a/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go b/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go index 0b9d05787a6e1..73673e977b883 100644 --- a/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go +++ b/cmd/argocd-git-ask-pass/commands/argocd_git_ask_pass.go @@ -9,7 +9,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/argoproj/argo-cd/v2/reposerver/askpass" + "github.com/argoproj/argo-cd/v2/util/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" diff --git a/cmd/argocd-k8s-auth/commands/azure.go b/cmd/argocd-k8s-auth/commands/azure.go index f4c3b9d3c96b9..287b8d457aee1 100644 --- a/cmd/argocd-k8s-auth/commands/azure.go +++ b/cmd/argocd-k8s-auth/commands/azure.go @@ -1,6 +1,7 @@ package commands import ( + "fmt" "os" "github.com/Azure/kubelogin/pkg/token" @@ -19,24 +20,26 @@ const ( ) func newAzureCommand() *cobra.Command { - o := token.NewOptions() - // we'll use default of WorkloadIdentityLogin for the login flow - o.LoginMethod = token.WorkloadIdentityLogin - o.ServerID = DEFAULT_AAD_SERVER_APPLICATION_ID command := &cobra.Command{ Use: "azure", Run: func(c *cobra.Command, args []string) { - o.UpdateFromEnv() + o := token.OptionsWithEnv() + if o.LoginMethod == "" { // no environment variable overrides + // we'll use default of WorkloadIdentityLogin for the login flow + o.LoginMethod = token.WorkloadIdentityLogin + } + o.ServerID = DEFAULT_AAD_SERVER_APPLICATION_ID if v, ok := os.LookupEnv(envServerApplicationID); ok { o.ServerID = v } if v, ok := os.LookupEnv(envEnvironmentName); ok { o.Environment = v } - plugin, err := token.New(&o) + tp, err := token.GetTokenProvider(o) errors.CheckError(err) - err = plugin.Do() + tok, err := tp.GetAccessToken(c.Context()) errors.CheckError(err) + _, _ = fmt.Fprint(os.Stdout, formatJSON(tok.Token, tok.ExpiresOn)) }, } return command diff --git a/cmd/argocd-notification/commands/controller.go b/cmd/argocd-notification/commands/controller.go index 7245a0b75a667..6f2dcc86a569d 100644 --- a/cmd/argocd-notification/commands/controller.go +++ b/cmd/argocd-notification/commands/controller.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "os/signal" + "runtime/debug" "strings" "sync" "syscall" @@ -115,6 +116,13 @@ func NewCommand() *cobra.Command { return fmt.Errorf("unknown log format '%s'", logFormat) } + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + tlsConfig := apiclient.TLSConfiguration{ DisableTLS: argocdRepoServerPlaintext, StrictValidation: argocdRepoServerStrictTLS, diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index ec863c26647f0..19d9a2a1e4b12 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "os/signal" + "runtime/debug" "sync" "syscall" "time" @@ -22,10 +23,10 @@ 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" + "github.com/argoproj/argo-cd/v2/util/askpass" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/env" @@ -75,6 +76,7 @@ func NewCommand() *cobra.Command { helmRegistryMaxIndexSize string disableManifestMaxExtractedSize bool includeHiddenDirectories bool + cmpUseManifestGeneratePaths bool ) command := cobra.Command{ Use: cliName, @@ -95,6 +97,13 @@ func NewCommand() *cobra.Command { cli.SetLogFormat(cmdutil.LogFormat) cli.SetLogLevel(cmdutil.LogLevel) + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + if !disableTLS { var err error tlsConfigCustomizer, err = tlsConfigCustomizerSrc() @@ -121,7 +130,7 @@ func NewCommand() *cobra.Command { askPassServer := askpass.NewServer(askpass.SocketPath) metricsServer := metrics.NewMetricsServer() - cacheutil.CollectMetrics(redisClient, metricsServer) + cacheutil.CollectMetrics(redisClient, metricsServer, nil) server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{ ParallelismLimit: parallelismLimit, PauseGenerationAfterFailedGenerationAttempts: pauseGenerationAfterFailedGenerationAttempts, @@ -136,6 +145,7 @@ func NewCommand() *cobra.Command { HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(), HelmRegistryMaxIndexSize: helmRegistryMaxIndexSizeQuantity.ToDec().Value(), IncludeHiddenDirectories: includeHiddenDirectories, + CMPUseManifestGeneratePaths: cmpUseManifestGeneratePaths, }, askPassServer) errors.CheckError(err) @@ -241,6 +251,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&helmRegistryMaxIndexSize, "helm-registry-max-index-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_INDEX_SIZE", "1G"), "Maximum size of registry index file") command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted") command.Flags().BoolVar(&includeHiddenDirectories, "include-hidden-directories", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES", false), "Include hidden directories from Git") + command.Flags().BoolVar(&cmpUseManifestGeneratePaths, "plugin-use-manifest-generate-paths", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS", false), "Pass the resources described in argocd.argoproj.io/manifest-generate-paths value to the cmpserver to generate the application manifests.") tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command) cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, cacheutil.Options{ OnClientCreated: func(client *redis.Client) { diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index d1e9cf05f98d5..0b89dad23e853 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math" + "runtime/debug" "strings" "time" @@ -86,6 +87,7 @@ func NewCommand() *cobra.Command { applicationNamespaces []string enableProxyExtension bool webhookParallelism int + hydratorEnabled bool // ApplicationSet enableNewGitFileGlobbing bool @@ -119,6 +121,13 @@ func NewCommand() *cobra.Command { cli.SetLogLevel(cmdutil.LogLevel) cli.SetGLogLevel(glogLevel) + // Recover from panic and log the error using the configured logger instead of the default. + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Fatal("Recovered from panic: ", r) + } + }() + config, err := clientConfig.ClientConfig() errors.CheckError(err) errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) @@ -155,6 +164,7 @@ func NewCommand() *cobra.Command { controllerClient, err := client.New(config, client.Options{Scheme: scheme}) errors.CheckError(err) controllerClient = client.NewDryRunClient(controllerClient) + controllerClient = client.NewNamespacedClient(controllerClient, namespace) // Load CA information to use for validating connections to the // repository server, if strict TLS validation was requested. @@ -234,6 +244,7 @@ func NewCommand() *cobra.Command { EnableProxyExtension: enableProxyExtension, WebhookParallelism: webhookParallelism, EnableK8sEvent: enableK8sEvent, + HydratorEnabled: hydratorEnabled, } appsetOpts := server.ApplicationSetOpts{ @@ -249,22 +260,25 @@ func NewCommand() *cobra.Command { stats.RegisterHeapDumper("memprofile") argocd := server.NewServer(ctx, argoCDOpts, appsetOpts) argocd.Init(ctx) - lns, err := argocd.Listen() - errors.CheckError(err) for { var closer func() - ctx, cancel := context.WithCancel(ctx) + serverCtx, cancel := context.WithCancel(ctx) + lns, err := argocd.Listen() + errors.CheckError(err) if otlpAddress != "" { - closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) + closer, err = traceutil.InitTracer(serverCtx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } } - argocd.Run(ctx, lns) - cancel() + argocd.Run(serverCtx, lns) if closer != nil { closer() } + cancel() + if argocd.TerminateRequested() { + break + } } }, Example: templates.Examples(` @@ -309,6 +323,7 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&enableProxyExtension, "enable-proxy-extension", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_PROXY_EXTENSION", false), "Enable Proxy Extension feature") command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently") command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)") + command.Flags().BoolVar(&hydratorEnabled, "hydrator-enabled", env.ParseBoolFromEnv("ARGOCD_HYDRATOR_ENABLED", false), "Feature flag to enable Hydrator. Default (\"false\")") // Flags related to the applicationSet component. command.Flags().StringVar(&scmRootCAPath, "appset-scm-root-ca-path", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH", ""), "Provide Root CA Path for self-signed TLS Certificates") diff --git a/cmd/argocd/commands/account.go b/cmd/argocd/commands/account.go index 0466cb142a0e1..03fe9932ee23c 100644 --- a/cmd/argocd/commands/account.go +++ b/cmd/argocd/commands/account.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" accountpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/account" "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" @@ -432,8 +433,14 @@ argocd account delete-token --account ID`, if account == "" { account = getCurrentAccount(ctx, clientset).Username } - _, err := client.DeleteToken(ctx, &accountpkg.DeleteTokenRequest{Name: account, Id: id}) - errors.CheckError(err) + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete '%s' token? [y/n]", id)) + if canDelete { + _, err := client.DeleteToken(ctx, &accountpkg.DeleteTokenRequest{Name: account, Id: id}) + errors.CheckError(err) + } else { + fmt.Printf("The command to delete '%s' was cancelled.\n", id) + } }, } cmd.Flags().StringVarP(&account, "account", "a", "", "Account name. Defaults to the current account.") diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index e8869493d05fc..0eb799b322570 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -188,12 +188,12 @@ func NewDiffReconcileResults() *cobra.Command { func toUnstructured(val interface{}) (*unstructured.Unstructured, error) { data, err := json.Marshal(val) if err != nil { - return nil, err + return nil, fmt.Errorf("error while marhsalling value: %w", err) } res := make(map[string]interface{}) err = json.Unmarshal(data, &res) if err != nil { - return nil, err + return nil, fmt.Errorf("error while unmarhsalling data: %w", err) } return &unstructured.Unstructured{Object: res}, nil } @@ -227,7 +227,7 @@ func diffReconcileResults(res1 reconcileResults, res2 reconcileResults) error { for k, v := range resMap2 { secondUn, err := toUnstructured(v) if err != nil { - return err + return fmt.Errorf("error converting second resource of second map to unstructure: %w", err) } pairs = append(pairs, diffPair{name: k, first: nil, second: secondUn}) } @@ -338,7 +338,7 @@ func saveToFile(err error, outputFormat string, result reconcileResults, outputP func getReconcileResults(ctx context.Context, appClientset appclientset.Interface, namespace string, selector string) ([]appReconcileResult, error) { appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { - return nil, err + return nil, fmt.Errorf("error listing namespaced apps: %w", err) } var items []appReconcileResult @@ -389,11 +389,11 @@ func reconcileApplications( return nil }, []string{}, []string{}) if err != nil { - return nil, err + return nil, fmt.Errorf("error starting new metrics server: %w", err) } stateCache := createLiveStateCache(argoDB, appInformer, settingsMgr, server) if err := stateCache.Init(); err != nil { - return nil, err + return nil, fmt.Errorf("error initializing state cache: %w", err) } cache := appstatecache.NewCache( @@ -406,7 +406,7 @@ func reconcileApplications( appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { - return nil, err + return nil, fmt.Errorf("error listing namespaced apps: %w", err) } sort.Slice(appsList.Items, func(i, j int) bool { @@ -429,7 +429,7 @@ func reconcileApplications( proj, err := projLister.AppProjects(namespace).Get(app.Spec.Project) if err != nil { - return nil, err + return nil, fmt.Errorf("error getting namespaced project: %w", err) } sources := make([]v1alpha1.ApplicationSource, 0) @@ -439,7 +439,7 @@ func reconcileApplications( res, err := appStateManager.CompareAppState(&app, proj, revisions, sources, false, false, nil, false, false) if err != nil { - return nil, err + return nil, fmt.Errorf("error comparing app states: %w", err) } items = append(items, appReconcileResult{ Name: app.Name, diff --git a/cmd/argocd/commands/admin/app_test.go b/cmd/argocd/commands/admin/app_test.go index cadce3e857009..964d23ccab696 100644 --- a/cmd/argocd/commands/admin/app_test.go +++ b/cmd/argocd/commands/admin/app_test.go @@ -91,7 +91,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { appClientset := appfake.NewSimpleClientset(app, proj) deployment := test.NewDeployment() - kubeClientset := kubefake.NewSimpleClientset(deployment, &cm) + kubeClientset := kubefake.NewClientset(deployment, &cm) clusterCache := clustermocks.ClusterCache{} clusterCache.On("IsNamespaced", mock.Anything).Return(true, nil) clusterCache.On("GetGVKParser", mock.Anything).Return(nil) diff --git a/cmd/argocd/commands/admin/backup.go b/cmd/argocd/commands/admin/backup.go index 918bbc234b9a2..b644b34e860b1 100644 --- a/cmd/argocd/commands/admin/backup.go +++ b/cmd/argocd/commands/admin/backup.go @@ -16,10 +16,12 @@ import ( "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/yaml" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/localconfig" secutil "github.com/argoproj/argo-cd/v2/util/security" ) @@ -137,6 +139,7 @@ func NewImportCommand() *cobra.Command { verbose bool stopOperation bool ignoreTracking bool + promptsEnabled bool applicationNamespaces []string applicationsetNamespaces []string ) @@ -308,6 +311,8 @@ func NewImportCommand() *cobra.Command { } } + promptUtil := utils.NewPrompt(promptsEnabled) + // Delete objects not in backup for key, liveObj := range pruneObjects { if prune { @@ -335,13 +340,19 @@ func NewImportCommand() *cobra.Command { log.Fatalf("Unexpected kind '%s' in prune list", key.Kind) } isForbidden := false + if !dryRun { - err = dynClient.Delete(ctx, key.Name, v1.DeleteOptions{}) - if apierr.IsForbidden(err) || apierr.IsNotFound(err) { - isForbidden = true - log.Warnf("%s/%s %s: %v\n", key.Group, key.Kind, key.Name, err) + canPrune := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to prune %s/%s %s ? [y/n]", key.Group, key.Kind, key.Name)) + if canPrune { + err = dynClient.Delete(ctx, key.Name, v1.DeleteOptions{}) + if apierr.IsForbidden(err) || apierr.IsNotFound(err) { + isForbidden = true + log.Warnf("%s/%s %s: %v\n", key.Group, key.Kind, key.Name, err) + } else { + errors.CheckError(err) + } } else { - errors.CheckError(err) + fmt.Printf("The command to prune %s/%s %s was cancelled.\n", key.Group, key.Kind, key.Name) } } if !isForbidden { @@ -362,6 +373,7 @@ func NewImportCommand() *cobra.Command { command.Flags().BoolVar(&stopOperation, "stop-operation", false, "Stop any existing operations") command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to which import of applications is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) + command.PersistentFlags().BoolVar(&promptsEnabled, "prompts-enabled", localconfig.GetPromptsEnabled(true), "Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.") return &command } diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 48ee0254fd1b7..034b650adfa10 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -565,7 +565,9 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub cluster, err := db.NewDB(namespace, settings.NewSettingsManager(ctx, kubeclientset, namespace), kubeclientset).GetCluster(ctx, serverUrl) errors.CheckError(err) - err = kube.WriteKubeConfig(cluster.RawRestConfig(), namespace, output) + rawConfig, err := cluster.RawRestConfig() + errors.CheckError(err) + err = kube.WriteKubeConfig(rawConfig, namespace, output) errors.CheckError(err) }, } @@ -615,7 +617,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command clientConfig := clientcmd.NewDefaultClientConfig(*cfgAccess, &overrides) conf, err := clientConfig.ClientConfig() errors.CheckError(err) - kubeClientset := fake.NewSimpleClientset() + kubeClientset := fake.NewClientset() var awsAuthConf *v1alpha1.AWSAuthConfig var execProviderConf *v1alpha1.ExecProviderConfig @@ -678,7 +680,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command command.PersistentFlags().StringVar(&pathOpts.LoadingRules.ExplicitPath, pathOpts.ExplicitFileFlag, pathOpts.LoadingRules.ExplicitPath, "use a particular kubeconfig file") command.Flags().StringVar(&bearerToken, "bearer-token", "", "Authentication token that should be used to access K8S API server") command.Flags().BoolVar(&generateToken, "generate-bearer-token", false, "Generate authentication token that should be used to access K8S API server") - command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "argocd-manager", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be used", clusterauth.ArgoCDManagerServiceAccount)) + command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "argocd-manager", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default %q SA will be used", clusterauth.ArgoCDManagerServiceAccount)) command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace") command.Flags().StringVarP(&outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml") command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)") diff --git a/cmd/argocd/commands/admin/project.go b/cmd/argocd/commands/admin/project.go index 9ba14ab80d961..3570afbb1a61d 100644 --- a/cmd/argocd/commands/admin/project.go +++ b/cmd/argocd/commands/admin/project.go @@ -50,13 +50,13 @@ func NewGenProjectSpecCommand() *cobra.Command { Short: "Generate declarative config for a project", Example: templates.Examples(` # Generate a YAML configuration for a project named "myproject" - argocd admin projects generate-spec myproject + argocd admin proj generate-spec myproject # Generate a JSON configuration for a project named "anotherproject" and specify an output file - argocd admin projects generate-spec anotherproject --output json --file config.json + argocd admin proj generate-spec anotherproject --output json --file config.json # Generate a YAML configuration for a project named "someproject" and write it back to the input file - argocd admin projects generate-spec someproject --inline + argocd admin proj generate-spec someproject --inline `), Run: func(c *cobra.Command, args []string) { @@ -155,10 +155,10 @@ func NewUpdatePolicyRuleCommand() *cobra.Command { Use: "update-role-policy PROJECT_GLOB MODIFICATION ACTION", Short: "Implement bulk project role update. Useful to back-fill existing project policies or remove obsolete actions.", Example: ` # Add policy that allows executing any action (action/*) to roles which name matches to *deployer* in all projects - argocd admin projects update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow + argocd admin proj update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow # Remove policy that which manages running (action/*) from all roles which name matches *deployer* in all projects - argocd admin projects update-role-policy '*' remove override --role '*deployer*' + argocd admin proj update-role-policy '*' remove override --role '*deployer*' `, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/cmd/argocd/commands/admin/redis_initial_password.go b/cmd/argocd/commands/admin/redis_initial_password.go index 3f89b54010659..f54741773fa21 100644 --- a/cmd/argocd/commands/admin/redis_initial_password.go +++ b/cmd/argocd/commands/admin/redis_initial_password.go @@ -45,9 +45,14 @@ func NewRedisInitialPasswordCommand() *cobra.Command { namespace, _, err := clientConfig.Namespace() errors.CheckError(err) - redisInitialPasswordSecretName := common.DefaultRedisInitialPasswordSecretName - redisInitialPasswordKey := common.DefaultRedisInitialPasswordKey - fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) + // redisInitialCredentials is the kubernetes secret containing + // the redis password + redisInitialCredentials := common.RedisInitialCredentials + + // redisInitialCredentialsKey is the key in the redisInitialCredentials + // secret which maps to the redis password + redisInitialCredentialsKey := common.RedisInitialCredentialsKey + fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialCredentials, redisInitialCredentialsKey) config, err := clientConfig.ClientConfig() errors.CheckError(err) @@ -59,11 +64,11 @@ func NewRedisInitialPasswordCommand() *cobra.Command { errors.CheckError(err) data := map[string][]byte{ - redisInitialPasswordKey: []byte(randomPassword), + redisInitialCredentialsKey: []byte(randomPassword), } secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: redisInitialPasswordSecretName, + Name: redisInitialCredentials, Namespace: namespace, }, Data: data, @@ -74,14 +79,14 @@ func NewRedisInitialPasswordCommand() *cobra.Command { errors.CheckError(err) } - fmt.Println("Argo CD Redis secret state confirmed: secret name argocd-redis.") - secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialPasswordSecretName, v1.GetOptions{}) + fmt.Printf("Argo CD Redis secret state confirmed: secret name %s.\n", redisInitialCredentials) + secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialCredentials, v1.GetOptions{}) errors.CheckError(err) - if _, ok := secret.Data[redisInitialPasswordKey]; ok { + if _, ok := secret.Data[redisInitialCredentialsKey]; ok { fmt.Println("Password secret is configured properly.") } else { - err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialPasswordKey, redisInitialPasswordSecretName) + err := fmt.Errorf("key %s doesn't exist in secret %s. \n", redisInitialCredentialsKey, redisInitialCredentials) errors.CheckError(err) } }, diff --git a/cmd/argocd/commands/admin/repo.go b/cmd/argocd/commands/admin/repo.go index ea55b341b486c..84933ab0c0cc5 100644 --- a/cmd/argocd/commands/admin/repo.go +++ b/cmd/argocd/commands/admin/repo.go @@ -150,7 +150,7 @@ func NewGenRepoSpecCommand() *cobra.Command { }, }, } - kubeClientset := fake.NewSimpleClientset(argoCDCM) + kubeClientset := fake.NewClientset(argoCDCM) settingsMgr := settings.NewSettingsManager(ctx, kubeClientset, ArgoCDNamespace) argoDB := db.NewDB(ArgoCDNamespace, settingsMgr, kubeClientset) diff --git a/cmd/argocd/commands/admin/settings.go b/cmd/argocd/commands/admin/settings.go index 7cd49b0c94031..85baf9bfd1389 100644 --- a/cmd/argocd/commands/admin/settings.go +++ b/cmd/argocd/commands/admin/settings.go @@ -119,7 +119,7 @@ func (opts *settingsOpts) createSettingsManager(ctx context.Context) (*settings. } } setSettingsMeta(argocdSecret) - clientset := fake.NewSimpleClientset(argocdSecret, argocdCM) + clientset := fake.NewClientset(argocdSecret, argocdCM) manager := settings.NewSettingsManager(ctx, clientset, "default") errors.CheckError(manager.ResyncInformers()) @@ -579,7 +579,7 @@ func NewResourceActionRunCommand(cmdCtx commandContext) *cobra.Command { Short: "Executes resource action", Long: "Executes resource action using the lua script configured in the 'resource.customizations' field of 'argocd-cm' ConfigMap and outputs updated fields", Example: ` -argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --argocd-cm-path ./argocd-cm.yaml`, +argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argocd-cm-path ./argocd-cm.yaml`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/cmd/argocd/commands/admin/settings_rbac_test.go b/cmd/argocd/commands/admin/settings_rbac_test.go index 9fe9ab6953a68..7e052ea2c1f8d 100644 --- a/cmd/argocd/commands/admin/settings_rbac_test.go +++ b/cmd/argocd/commands/admin/settings_rbac_test.go @@ -147,7 +147,7 @@ func Test_PolicyFromK8s(t *testing.T) { ctx := context.Background() require.NoError(t, err) - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-rbac-cm", Namespace: "argocd", @@ -280,7 +280,7 @@ p, role:user, logs, get, .*/.*, allow p, role:user, exec, create, .*/.*, allow ` - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-rbac-cm", Namespace: "argocd", diff --git a/cmd/argocd/commands/admin/settings_test.go b/cmd/argocd/commands/admin/settings_test.go index 4db8ae7ba5eeb..9ff9af5411f97 100644 --- a/cmd/argocd/commands/admin/settings_test.go +++ b/cmd/argocd/commands/admin/settings_test.go @@ -45,7 +45,7 @@ func captureStdout(callback func()) (string, error) { func newSettingsManager(data map[string]string) *settings.SettingsManager { ctx := context.Background() - clientset := fake.NewSimpleClientset(&v1.ConfigMap{ + clientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: common.ArgoCDConfigMapName, @@ -200,8 +200,7 @@ admissionregistration.k8s.io/MutatingWebhookConfiguration: require.NoError(t, err) assert.Contains(t, summary, tc.containsSummary) } else if tc.containsError != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tc.containsError) + assert.ErrorContains(t, err, tc.containsError) } }) } diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 00c5c14834e2f..3cfc5f13f1d9c 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -8,6 +8,7 @@ import ( "io" "os" "reflect" + "slices" "sort" "strconv" "strings" @@ -27,6 +28,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" k8swatch "k8s.io/apimachinery/pkg/watch" @@ -34,6 +36,7 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" "github.com/argoproj/argo-cd/v2/controller" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" @@ -98,6 +101,7 @@ func NewApplicationCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman command.AddCommand(NewApplicationLogsCommand(clientOpts)) command.AddCommand(NewApplicationAddSourceCommand(clientOpts)) command.AddCommand(NewApplicationRemoveSourceCommand(clientOpts)) + command.AddCommand(NewApplicationConfirmDeletionCommand(clientOpts)) return command } @@ -108,6 +112,7 @@ type watchOpts struct { suspended bool degraded bool delete bool + hydrated bool } // NewApplicationCreateCommand returns a new instance of an `argocd app create` command @@ -314,6 +319,17 @@ func printHeader(acdClient argocdclient.Client, app *argoappv1.Application, ctx } } +// getSourceNameToPositionMap returns a map of source name to position +func getSourceNameToPositionMap(app *argoappv1.Application) map[string]int64 { + sourceNameToPosition := make(map[string]int64) + for i, s := range app.Spec.Sources { + if s.Name != "" { + sourceNameToPosition[s.Name] = int64(i + 1) + } + } + return sourceNameToPosition +} + // NewApplicationGetCommand returns a new instance of an `argocd app get` command func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( @@ -324,6 +340,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com showOperation bool appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "get APPNAME", @@ -347,6 +364,9 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app argocd app get my-app --show-params --source-position 1 + # Show application parameters and overrides for a source named "test" + argocd app get my-app --show-params --source-name test + # Refresh application data when retrieving argocd app get my-app --refresh @@ -379,7 +399,21 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com }) errors.CheckError(err) - if app.Spec.HasMultipleSources() { + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + + // check for source position if --show-params is set + if app.Spec.HasMultipleSources() && showParams { if sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) } @@ -433,6 +467,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com command.Flags().BoolVar(&hardRefresh, "hard-refresh", false, "Refresh application data as well as target manifests cache") command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only get application from namespace") command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") + command.Flags().StringVar(&sourceName, "source-name", "", "Name of the source from the list of sources of the app.") return command } @@ -585,8 +620,8 @@ func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *ar var status string var allow, deny, inactiveAllows bool if windows.HasWindows() { - active := windows.Active() - if active.HasWindows() { + active, err := windows.Active() + if err == nil && active.HasWindows() { for _, w := range *active { if w.Kind == "deny" { deny = true @@ -595,13 +630,14 @@ func printAppSummaryTable(app *argoappv1.Application, appURL string, windows *ar } } } - if windows.InactiveAllows().HasWindows() { + inactiveAllowWindows, err := windows.InactiveAllows() + if err == nil && inactiveAllowWindows.HasWindows() { inactiveAllows = true } - s := windows.CanSync(true) if deny || !deny && !allow && inactiveAllows { - if s { + s, err := windows.CanSync(true) + if err == nil && s { status = "Manual Allowed" } else { status = "Sync Denied" @@ -761,6 +797,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com appOpts cmdutil.AppOptions appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "set APPNAME", @@ -775,6 +812,9 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set and override application parameters for a source named "test" under spec.sources of app my-app. + argocd app set my-app --source-name test --repo https://github.com/argoproj/argocd-example-apps.git + # Set application parameters and specify the namespace argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace `), @@ -793,6 +833,20 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) + sourceName = appOpts.SourceName + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) @@ -856,6 +910,7 @@ func (o *unsetOpts) KustomizeIsZero() bool { // NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var sourcePosition int + var sourceName string appOpts := cmdutil.AppOptions{} opts := unsetOpts{} var appNamespace string @@ -871,6 +926,9 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C # Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app unset my-app --source-position 1 --namesuffix + # Unset kustomize override suffix for source named "test" under spec.sources of app my-app. + argocd app unset my-app --source-name test --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM`, @@ -888,6 +946,20 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) + sourceName = appOpts.SourceName + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) @@ -909,13 +981,20 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C } cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourcePosition) - _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ - Name: &app.Name, - Spec: &app.Spec, - Validate: &appOpts.Validate, - AppNamespace: &appNs, - }) - errors.CheckError(err) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canUnset := promptUtil.Confirm("Are you sure you want to unset the parameters? [y/n]") + if canUnset { + _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ + Name: &app.Name, + Spec: &app.Spec, + Validate: &appOpts.Validate, + AppNamespace: &appNs, + }) + errors.CheckError(err) + } else { + fmt.Println("The command to unset the parameters has been cancelled.") + } }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Unset application parameters in namespace") @@ -1080,17 +1159,18 @@ func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, proj ) []string { source := app.Spec.GetSource() res, err := repository.GenerateManifests(ctx, local, localRepoRoot, source.TargetRevision, &repoapiclient.ManifestRequest{ - Repo: &argoappv1.Repository{Repo: source.RepoURL}, - AppLabelKey: appLabelKey, - AppName: app.Name, - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: kubeVersion, - ApiVersions: apiVersions, - TrackingMethod: trackingMethod, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: &argoappv1.Repository{Repo: source.RepoURL}, + AppLabelKey: appLabelKey, + AppName: app.Name, + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: kubeVersion, + ApiVersions: apiVersions, + TrackingMethod: trackingMethod, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: app.GetAnnotation(argoappv1.AnnotationKeyManifestGeneratePaths), }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil) errors.CheckError(err) @@ -1139,6 +1219,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co refresh bool hardRefresh bool exitCode bool + diffExitCode int local string revision string localRepoRoot string @@ -1147,6 +1228,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appNamespace string revisions []string sourcePositions []int64 + sourceNames []string ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts ) shortDesc := "Perform a diff against the target and live state." @@ -1162,8 +1244,16 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co os.Exit(2) } - if len(revisions) != len(sourcePositions) { - errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same.")) + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) + } + + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } clientset := headless.NewClientOrDie(clientOpts, c) @@ -1177,6 +1267,18 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) + if len(sourceNames) > 0 { + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ApplicationName: &appName, AppNamespace: &appNs}) errors.CheckError(err) conn, settingsIf := clientset.NewSettingsClientOrDie() @@ -1241,13 +1343,14 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co proj := getProject(c, clientOpts, ctx, app.Spec.Project) foundDiffs := findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, diffOption, ignoreNormalizerOpts) if foundDiffs && exitCode { - os.Exit(1) + os.Exit(diffExitCode) } }, } command.Flags().BoolVar(&refresh, "refresh", false, "Refresh application data when retrieving") command.Flags().BoolVar(&hardRefresh, "hard-refresh", false, "Refresh application data as well as target manifests cache") - command.Flags().BoolVar(&exitCode, "exit-code", true, "Return non-zero exit code when there is a diff") + command.Flags().BoolVar(&exitCode, "exit-code", true, "Return non-zero exit code when there is a diff. May also return non-zero exit code if there is an error.") + command.Flags().IntVar(&diffExitCode, "diff-exit-code", 1, "Return specified exit code when there is a diff. Typical error code is 20.") command.Flags().StringVar(&local, "local", "", "Compare live app to a local manifests") command.Flags().StringVar(&revision, "revision", "", "Compare live app to a particular revision") command.Flags().StringVar(&localRepoRoot, "local-repo-root", "/", "Path to the repository root. Used together with --local allows setting the repository root") @@ -1256,6 +1359,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only render the difference in namespace") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout") return command } @@ -1374,7 +1478,7 @@ func groupObjsForDiff(resources *application.ManagedResourcesResponse, objs map[ } if local, ok := objs[key]; ok || live != nil { if local != nil && !kube.IsCRD(local) { - err = resourceTracking.SetAppInstance(local, argoSettings.AppLabelKey, appName, namespace, argoappv1.TrackingMethod(argoSettings.GetTrackingMethod())) + err = resourceTracking.SetAppInstance(local, argoSettings.AppLabelKey, appName, namespace, argoappv1.TrackingMethod(argoSettings.GetTrackingMethod()), argoSettings.GetInstallationID()) errors.CheckError(err) } @@ -1429,8 +1533,6 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. conn, appIf := acdClient.NewApplicationClientOrDie() defer argoio.Close(conn) var isTerminal bool = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) - var isConfirmAll bool = false - numOfApps := len(args) promptFlag := c.Flag("yes") if promptFlag.Changed && promptFlag.Value.String() == "true" { noPrompt = true @@ -1443,6 +1545,16 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. appNames = args } + numOfApps := len(appNames) + + // This is for backward compatibility, + // before we showed the prompts only when condition cascade && isTerminal && !noPrompt is true + promptUtil := utils.NewPrompt(cascade && isTerminal && !noPrompt) + var ( + confirmAll = false + confirm = false + ) + for _, appFullName := range appNames { appName, appNs := argo.ParseFromQualifiedName(appFullName, appNamespace) appDeleteReq := application.ApplicationDeleteRequest{ @@ -1455,38 +1567,21 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. if c.Flag("propagation-policy").Changed { appDeleteReq.PropagationPolicy = &propagationPolicy } - if cascade && isTerminal && !noPrompt { - var lowercaseAnswer string - if numOfApps == 1 { - lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n] ") - } else { - if !isConfirmAll { - lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n/A] where 'A' is to delete all specified apps and their resources without prompting ") - if lowercaseAnswer == "a" { - lowercaseAnswer = "y" - isConfirmAll = true - } - } else { - lowercaseAnswer = "y" - } - } - if lowercaseAnswer == "y" { - _, err := appIf.Delete(ctx, &appDeleteReq) - errors.CheckError(err) - if wait { - checkForDeleteEvent(ctx, acdClient, appFullName) - } - fmt.Printf("application '%s' deleted\n", appFullName) - } else { - fmt.Println("The command to delete '" + appFullName + "' was cancelled.") - } - } else { + messageForSingle := "Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n] " + messageForAll := "Are you sure you want to delete '" + appFullName + "' and all its resources? [y/n/a] where 'a' is to delete all specified apps and their resources without prompting " + + if !confirmAll { + confirm, confirmAll = promptUtil.ConfirmBaseOnCount(messageForSingle, messageForAll, numOfApps) + } + if confirm || confirmAll { _, err := appIf.Delete(ctx, &appDeleteReq) errors.CheckError(err) - if wait { checkForDeleteEvent(ctx, acdClient, appFullName) } + fmt.Printf("application '%s' deleted\n", appFullName) + } else { + fmt.Println("The command to delete '" + appFullName + "' was cancelled.") } } }, @@ -1645,6 +1740,7 @@ func formatConditionsSummary(app argoappv1.Application) string { } summary := "" if len(items) > 0 { + slices.Sort(items) summary = strings.Join(items, ",") } return summary @@ -1788,6 +1884,7 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().BoolVar(&watch.suspended, "suspended", false, "Wait for suspended") command.Flags().BoolVar(&watch.degraded, "degraded", false, "Wait for degraded") command.Flags().BoolVar(&watch.delete, "delete", false, "Wait for delete") + command.Flags().BoolVar(&watch.hydrated, "hydrated", false, "Wait for hydration operations") command.Flags().StringVarP(&selector, "selector", "l", "", "Wait for apps by label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints.") command.Flags().StringArrayVar(&resources, "resource", []string{}, fmt.Sprintf("Sync only specific resources as GROUP%[1]sKIND%[1]sNAME or %[2]sGROUP%[1]sKIND%[1]sNAME. Fields may be blank and '*' can be used. This option may be specified repeatedly", resourceFieldDelimiter, resourceExcludeIndicator)) command.Flags().BoolVar(&watch.operation, "operation", false, "Wait for pending operations") @@ -1829,6 +1926,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co revision string revisions []string sourcePositions []int64 + sourceNames []string resources []string labels []string selector string @@ -1872,7 +1970,8 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)' # Sync a multi-source application for specific revision of specific sources - argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-names my-chart --revisions 0.0.2 --source-names my-values # Sync a specific resource # Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME @@ -1897,10 +1996,22 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co log.Fatal("Cannot use --revisions and --source-positions options when 0 or more than 1 application names are passed as argument(s)") } - if len(revisions) != len(sourcePositions) { + if len(args) != 1 && (len(revisions) > 0 || len(sourceNames) > 0) { + log.Fatal("Cannot use --revisions and --source-names options when 0 or more than 1 application names are passed as argument(s)") + } + + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + log.Fatal("Only one of source-positions and source-names can be specified.") + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { log.Fatal("While using --revisions and --source-positions, length of values for both flags should be same.") } + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + log.Fatal("While using --revisions and --source-names, length of values for both flags should be same.") + } + for _, pos := range sourcePositions { if pos <= 0 { log.Fatal("source-position cannot be less than or equal to 0, Counting starts at 1") @@ -1914,6 +2025,22 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co selectedLabels, err := label.Parse(labels) errors.CheckError(err) + if len(args) == 1 && len(sourceNames) > 0 { + appName, _ := argo.ParseFromQualifiedName(args[0], appNamespace) + app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName}) + errors.CheckError(err) + + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + appNames := args if selector != "" || len(projects) > 0 { list, err := appIf.List(ctx, &application.ApplicationQuery{ @@ -2172,6 +2299,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") return command } @@ -2324,7 +2452,7 @@ func groupResourceStates(app *argoappv1.Application, selectedResources []*argoap } // check if resource health, sync and operation statuses matches watch options -func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string, operationStatus *argoappv1.Operation) bool { +func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string, operationStatus *argoappv1.Operation, hydrationFinished bool) bool { if watch.delete { return false } @@ -2354,7 +2482,8 @@ func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string synced := !watch.sync || syncStatus == string(argoappv1.SyncStatusCodeSynced) operational := !watch.operation || operationStatus == nil - return synced && healthCheckPassed && operational + hydrated := !watch.hydrated || hydrationFinished + return synced && healthCheckPassed && operational && hydrated } // resourceParentChild gets the latest state of the app and the latest state of the app's resource tree and then @@ -2518,13 +2647,15 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, } } + hydrationFinished := app.Status.SourceHydrator.CurrentOperation != nil && app.Status.SourceHydrator.CurrentOperation.Phase == argoappv1.HydrateOperationPhaseHydrated && app.Status.SourceHydrator.CurrentOperation.SourceHydrator.DeepEquals(app.Status.SourceHydrator.LastSuccessfulOperation.SourceHydrator) && app.Status.SourceHydrator.CurrentOperation.DrySHA == app.Status.SourceHydrator.LastSuccessfulOperation.DrySHA + var selectedResourcesAreReady bool // If selected resources are included, wait only on those resources, otherwise wait on the application as a whole. if len(selectedResources) > 0 { selectedResourcesAreReady = true for _, state := range getResourceStates(app, selectedResources) { - resourceIsReady := checkResourceStatus(watch, state.Health, state.Status, appEvent.Application.Operation) + resourceIsReady := checkResourceStatus(watch, state.Health, state.Status, appEvent.Application.Operation, hydrationFinished) if !resourceIsReady { selectedResourcesAreReady = false break @@ -2532,7 +2663,7 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, } } else { // Wait on the application as a whole - selectedResourcesAreReady = checkResourceStatus(watch, string(app.Status.Health.Status), string(app.Status.Sync.Status), appEvent.Application.Operation) + selectedResourcesAreReady = checkResourceStatus(watch, string(app.Status.Health.Status), string(app.Status.Sync.Status), appEvent.Application.Operation, hydrationFinished) } if selectedResourcesAreReady && (!operationInProgress || !watch.operation) { @@ -2812,6 +2943,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob revision string revisions []string sourcePositions []int64 + sourceNames []string local string localRepoRoot string ) @@ -2825,6 +2957,9 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob # Get manifests for an application at a specific revision argocd app manifests my-app --revision 0.0.1 + # Get manifests for a multi-source application at specific revisions for specific sources + argocd app manifests my-app --revisions 0.0.1 --source-names src-base --revisions 0.0.2 --source-names src-values + # Get manifests for a multi-source application at specific revisions for specific sources argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 `), @@ -2836,8 +2971,16 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob os.Exit(1) } - if len(revisions) != len(sourcePositions) { - errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same.")) + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) + } + + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } for _, pos := range sourcePositions { @@ -2851,6 +2994,24 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob conn, appIf := clientset.NewApplicationClientOrDie() defer argoio.Close(conn) + app, err := appIf.Get(context.Background(), &application.ApplicationQuery{ + Name: &appName, + AppNamespace: &appNs, + }) + errors.CheckError(err) + + if len(sourceNames) > 0 { + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, @@ -2861,9 +3022,6 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob switch source { case "git": if local != "" { - app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName}) - errors.CheckError(err) - settingsConn, settingsIf := clientset.NewSettingsClientOrDie() defer argoio.Close(settingsConn) argoSettings, err := settingsIf.Get(context.Background(), &settings.SettingsQuery{}) @@ -2932,6 +3090,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob command.Flags().StringVar(&revision, "revision", "", "Show manifests at a specific revision") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for the source at position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") command.Flags().StringVar(&local, "local", "", "If set, show locally-generated manifests. Value is the absolute path to app manifests within the manifest repo. Example: '/home/username/apps/env/app-1'.") command.Flags().StringVar(&localRepoRoot, "local-repo-root", ".", "Path to the local repository root. Used together with --local allows setting the repository root. Example: '/home/username/apps'.") return command @@ -3080,7 +3239,7 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob Use: "add-source APPNAME", Short: "Adds a source to the list of sources in the application", Example: ` # Append a source to the list of sources in the application - argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook`, + argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --source-name guestbook`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() if len(args) != 1 { @@ -3138,13 +3297,17 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( sourcePosition int + sourceName string appNamespace string ) command := &cobra.Command{ Use: "remove-source APPNAME", - Short: "Remove a source from multiple sources application. Counting starts with 1. Default value is -1.", + Short: "Remove a source from multiple sources application.", Example: ` # Remove the source at position 1 from application's sources. Counting starts at 1. - argocd app remove-source myapplication --source-position 1`, + argocd app remove-source myapplication --source-position 1 + + # Remove the source named "test" from application's sources. + argocd app remove-source myapplication --source-name test`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -3153,7 +3316,7 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * os.Exit(1) } - if sourcePosition <= 0 { + if sourceName == "" && sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Value of source-position must be greater than 0")) } @@ -3170,6 +3333,19 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * }) errors.CheckError(err) + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if !app.Spec.HasMultipleSources() { errors.CheckError(fmt.Errorf("Application does not have multiple sources configured")) } @@ -3184,17 +3360,71 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * app.Spec.Sources = append(app.Spec.Sources[:sourcePosition-1], app.Spec.Sources[sourcePosition:]...) - _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ - Name: &app.Name, - Spec: &app.Spec, + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm("Are you sure you want to delete the source? [y/n]") + if canDelete { + _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ + Name: &app.Name, + Spec: &app.Spec, + AppNamespace: &appNs, + }) + errors.CheckError(err) + + fmt.Printf("Application '%s' updated successfully\n", app.ObjectMeta.Name) + } else { + fmt.Println("The command to delete the source was cancelled") + } + }, + } + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace of the target application where the source will be appended") + command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") + command.Flags().StringVar(&sourceName, "source-name", "", "Name of the source from the list of sources of the app.") + return command +} + +func NewApplicationConfirmDeletionCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + var appNamespace string + command := &cobra.Command{ + Use: "confirm-deletion APPNAME", + Short: "Confirms deletion/pruning of an application resources", + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + if len(args) != 1 { + c.HelpFunc()(c, args) + os.Exit(1) + } + + argocdClient := headless.NewClientOrDie(clientOpts, c) + conn, appIf := argocdClient.NewApplicationClientOrDie() + defer argoio.Close(conn) + + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) + + app, err := appIf.Get(ctx, &application.ApplicationQuery{ + Name: &appName, + Refresh: getRefreshType(false, false), AppNamespace: &appNs, }) errors.CheckError(err) + annotations := app.Annotations + if annotations == nil { + annotations = map[string]string{} + app.Annotations = annotations + } + annotations[common.AnnotationDeletionApproved] = metav1.Now().Format(time.RFC3339) + + _, err = appIf.Update(ctx, &application.ApplicationUpdateRequest{ + Application: app, + Validate: ptr.To(false), + Project: &app.Spec.Project, + }) + errors.CheckError(err) + fmt.Printf("Application '%s' updated successfully\n", app.ObjectMeta.Name) }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace of the target application where the source will be appended") - command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") return command } diff --git a/cmd/argocd/commands/app_resource_test.go b/cmd/argocd/commands/app_resource_test.go index 4a6cd50d6800f..171da12b471b7 100644 --- a/cmd/argocd/commands/app_resource_test.go +++ b/cmd/argocd/commands/app_resource_test.go @@ -6,6 +6,7 @@ import ( "text/tabwriter" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -37,9 +38,7 @@ func TestPrintTreeViewAppResources(t *testing.T) { w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() assert.Contains(t, output, "Rollout") @@ -78,9 +77,7 @@ func TestPrintTreeViewDetailedAppResources(t *testing.T) { w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() assert.Contains(t, output, "Rollout") diff --git a/cmd/argocd/commands/app_resources.go b/cmd/argocd/commands/app_resources.go index f86ab0669661b..e7cc47fa8b76a 100644 --- a/cmd/argocd/commands/app_resources.go +++ b/cmd/argocd/commands/app_resources.go @@ -5,6 +5,7 @@ import ( "os" "text/tabwriter" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" "github.com/argoproj/argo-cd/v2/cmd/util" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -130,23 +131,32 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) errors.CheckError(err) objectsToDelete, err := util.FilterResources(command.Flags().Changed("group"), resources.Items, group, kind, namespace, resourceName, all) errors.CheckError(err) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + for i := range objectsToDelete { obj := objectsToDelete[i] gvk := obj.GroupVersionKind() - _, err = appIf.DeleteResource(ctx, &applicationpkg.ApplicationResourceDeleteRequest{ - Name: &appName, - AppNamespace: &appNs, - Namespace: ptr.To(obj.GetNamespace()), - ResourceName: ptr.To(obj.GetName()), - Version: ptr.To(gvk.Version), - Group: ptr.To(gvk.Group), - Kind: ptr.To(gvk.Kind), - Force: &force, - Orphan: &orphan, - Project: ptr.To(project), - }) - errors.CheckError(err) - log.Infof("Resource '%s' deleted", obj.GetName()) + + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete %s/%s %s/%s ? [y/n]", gvk.Group, gvk.Kind, obj.GetNamespace(), obj.GetName())) + if canDelete { + _, err = appIf.DeleteResource(ctx, &applicationpkg.ApplicationResourceDeleteRequest{ + Name: &appName, + AppNamespace: &appNs, + Namespace: ptr.To(obj.GetNamespace()), + ResourceName: ptr.To(obj.GetName()), + Version: ptr.To(gvk.Version), + Group: ptr.To(gvk.Group), + Kind: ptr.To(gvk.Kind), + Force: &force, + Orphan: &orphan, + Project: ptr.To(project), + }) + errors.CheckError(err) + log.Infof("Resource '%s' deleted", obj.GetName()) + } else { + fmt.Printf("The command to delete %s/%s %s/%s was cancelled.\n", gvk.Group, gvk.Kind, obj.GetNamespace(), obj.GetName()) + } } } diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index ffd7d78329cd9..57aede02a5b49 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -136,13 +136,8 @@ func TestFindRevisionHistoryWithoutPassedId(t *testing.T) { } history, err := findRevisionHistory(&application, -1) - if err != nil { - t.Fatal("Find revision history should fail without errors") - } - - if history == nil { - t.Fatal("History should be found") - } + require.NoError(t, err, "Find revision history should fail without errors") + require.NotNil(t, history, "History should be found") } func TestPrintTreeViewAppGet(t *testing.T) { @@ -249,13 +244,8 @@ func TestFindRevisionHistoryWithoutPassedIdWithMultipleSources(t *testing.T) { } history, err := findRevisionHistory(&application, -1) - if err != nil { - t.Fatal("Find revision history should fail without errors") - } - - if history == nil { - t.Fatal("History should be found") - } + require.NoError(t, err, "Find revision history should fail without errors") + require.NotNil(t, history, "History should be found") } func TestDefaultWaitOptions(t *testing.T) { @@ -308,17 +298,9 @@ func TestFindRevisionHistoryWithoutPassedIdAndEmptyHistoryList(t *testing.T) { history, err := findRevisionHistory(&application, -1) - if err == nil { - t.Fatal("Find revision history should fail with errors") - } - - if history != nil { - t.Fatal("History should be empty") - } - - if err.Error() != "Application '' should have at least two successful deployments" { - t.Fatal("Find revision history should fail with correct error message") - } + require.Error(t, err, "Find revision history should fail with errors") + require.Nil(t, history, "History should be empty") + require.EqualError(t, err, "Application '' should have at least two successful deployments", "Find revision history should fail with correct error message") } func TestFindRevisionHistoryWithPassedId(t *testing.T) { @@ -346,17 +328,9 @@ func TestFindRevisionHistoryWithPassedId(t *testing.T) { } history, err := findRevisionHistory(&application, 3) - if err != nil { - t.Fatal("Find revision history should fail without errors") - } - - if history == nil { - t.Fatal("History should be found") - } - - if history.Revision != "123" { - t.Fatal("Failed to find correct history with correct revision") - } + require.NoError(t, err, "Find revision history should fail without errors") + require.NotNil(t, history, "History should be found") + require.Equal(t, "123", history.Revision, "Failed to find correct history with correct revision") } func TestFindRevisionHistoryWithPassedIdThatNotExist(t *testing.T) { @@ -385,17 +359,9 @@ func TestFindRevisionHistoryWithPassedIdThatNotExist(t *testing.T) { history, err := findRevisionHistory(&application, 4) - if err == nil { - t.Fatal("Find revision history should fail with errors") - } - - if history != nil { - t.Fatal("History should be not found") - } - - if err.Error() != "Application '' does not have deployment id '4' in history\n" { - t.Fatal("Find revision history should fail with correct error message") - } + require.Error(t, err, "Find revision history should fail with errors") + require.Nil(t, history, "History should be not found") + require.EqualError(t, err, "Application '' does not have deployment id '4' in history\n", "Find revision history should fail with correct error message") } func Test_groupObjsByKey(t *testing.T) { @@ -457,9 +423,7 @@ func TestFormatSyncPolicy(t *testing.T) { policy := formatSyncPolicy(app) - if policy != "Manual" { - t.Fatalf("Incorrect policy %q, should be Manual", policy) - } + require.Equalf(t, "Manual", policy, "Incorrect policy %q, should be Manual", policy) }) t.Run("Auto policy", func(t *testing.T) { @@ -473,9 +437,7 @@ func TestFormatSyncPolicy(t *testing.T) { policy := formatSyncPolicy(app) - if policy != "Auto" { - t.Fatalf("Incorrect policy %q, should be Auto", policy) - } + require.Equalf(t, "Auto", policy, "Incorrect policy %q, should be Auto", policy) }) t.Run("Auto policy with prune", func(t *testing.T) { @@ -491,9 +453,7 @@ func TestFormatSyncPolicy(t *testing.T) { policy := formatSyncPolicy(app) - if policy != "Auto-Prune" { - t.Fatalf("Incorrect policy %q, should be Auto-Prune", policy) - } + require.Equalf(t, "Auto-Prune", policy, "Incorrect policy %q, should be Auto-Prune", policy) }) } @@ -510,9 +470,7 @@ func TestFormatConditionSummary(t *testing.T) { } summary := formatConditionsSummary(app) - if summary != "" { - t.Fatalf("Incorrect summary %q, should be ", summary) - } + require.Equalf(t, "", summary, "Incorrect summary %q, should be ", summary) }) t.Run("Few conditions are defined", func(t *testing.T) { @@ -533,9 +491,28 @@ func TestFormatConditionSummary(t *testing.T) { } summary := formatConditionsSummary(app) - if summary != "type1(2),type2" && summary != "type2,type1(2)" { - t.Fatalf("Incorrect summary %q, should be type1(2),type2", summary) + require.Equalf(t, "type1(2),type2", summary, "Incorrect summary %q, should be type1(2),type2", summary) + }) + + t.Run("Conditions are sorted for idempotent summary", func(t *testing.T) { + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + Conditions: []v1alpha1.ApplicationCondition{ + { + Type: "type2", + }, + { + Type: "type1", + }, + { + Type: "type1", + }, + }, + }, } + + summary := formatConditionsSummary(app) + require.Equalf(t, "type1(2),type2", summary, "Incorrect summary %q, should be type1(2),type2", summary) }) } @@ -546,9 +523,7 @@ func TestPrintOperationResult(t *testing.T) { return nil }) - if output != "" { - t.Fatalf("Incorrect print operation output %q, should be ''", output) - } + require.Emptyf(t, output, "Incorrect print operation output %q, should be ''", output) }) t.Run("Operation state sync result is not empty", func(t *testing.T) { @@ -562,9 +537,7 @@ func TestPrintOperationResult(t *testing.T) { }) expectation := "Operation: Sync\nSync Revision: revision\nPhase: \nStart: 0001-01-01 00:00:00 +0000 UTC\nFinished: 2020-11-10 23:00:00 +0000 UTC\nDuration: 2333448h16m18.871345152s\n" - if output != expectation { - t.Fatalf("Incorrect print operation output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print operation output %q, should be %q", output, expectation) }) t.Run("Operation state sync result with message is not empty", func(t *testing.T) { @@ -579,9 +552,7 @@ func TestPrintOperationResult(t *testing.T) { }) expectation := "Operation: Sync\nSync Revision: revision\nPhase: \nStart: 0001-01-01 00:00:00 +0000 UTC\nFinished: 2020-11-10 23:00:00 +0000 UTC\nDuration: 2333448h16m18.871345152s\nMessage: test\n" - if output != expectation { - t.Fatalf("Incorrect print operation output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print operation output %q, should be %q", output, expectation) }) } @@ -617,9 +588,7 @@ func TestPrintApplicationHistoryTable(t *testing.T) { expectation := "SOURCE test\nID DATE REVISION\n1 0001-01-01 00:00:00 +0000 UTC 1\n2 0001-01-01 00:00:00 +0000 UTC 2\n3 0001-01-01 00:00:00 +0000 UTC 3\n" - if output != expectation { - t.Fatalf("Incorrect print operation output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print operation output %q, should be %q", output, expectation) } func TestPrintApplicationHistoryTableWithMultipleSources(t *testing.T) { @@ -696,9 +665,7 @@ func TestPrintApplicationHistoryTableWithMultipleSources(t *testing.T) { expectation := "SOURCE test\nID DATE REVISION\n0 0001-01-01 00:00:00 +0000 UTC 0\n\nSOURCE test-1\nID DATE REVISION\n1 0001-01-01 00:00:00 +0000 UTC 1a\n2 0001-01-01 00:00:00 +0000 UTC 2a\n3 0001-01-01 00:00:00 +0000 UTC 3a\n\nSOURCE test-2\nID DATE REVISION\n1 0001-01-01 00:00:00 +0000 UTC 1b\n2 0001-01-01 00:00:00 +0000 UTC 2b\n3 0001-01-01 00:00:00 +0000 UTC 3b\n" - if output != expectation { - t.Fatalf("Incorrect print operation output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print operation output %q, should be %q", output, expectation) } func TestPrintAppSummaryTable(t *testing.T) { @@ -912,9 +879,7 @@ func TestPrintAppConditions(t *testing.T) { return nil }) expectation := "CONDITION\tMESSAGE\tLAST TRANSITION\nDeletionError\ttest\t\nExcludedResourceWarning\ttest2\t\nRepeatedResourceWarning\ttest3\t\n" - if output != expectation { - t.Fatalf("Incorrect print app conditions output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print app conditions output %q, should be %q", output, expectation) } func TestPrintParams(t *testing.T) { @@ -991,9 +956,7 @@ func TestPrintParams(t *testing.T) { return nil }) - if output != tc.expectedOutput { - t.Fatalf("Incorrect print params output %q, should be %q\n", output, tc.expectedOutput) - } + require.Equalf(t, tc.expectedOutput, output, "Incorrect print params output %q, should be %q\n", output, tc.expectedOutput) }) } } @@ -1005,9 +968,7 @@ func TestAppUrlDefault(t *testing.T) { PlainText: true, }), "test") expectation := "http://localhost:80/applications/test" - if result != expectation { - t.Fatalf("Incorrect url %q, should be %q", result, expectation) - } + require.Equalf(t, result, expectation, "Incorrect url %q, should be %q", result, expectation) }) t.Run("https", func(t *testing.T) { result := appURLDefault(argocdclient.NewClientOrDie(&argocdclient.ClientOptions{ @@ -1015,18 +976,14 @@ func TestAppUrlDefault(t *testing.T) { PlainText: false, }), "test") expectation := "https://localhost/applications/test" - if result != expectation { - t.Fatalf("Incorrect url %q, should be %q", result, expectation) - } + require.Equalf(t, result, expectation, "Incorrect url %q, should be %q", result, expectation) }) } func TestTruncateString(t *testing.T) { result := truncateString("argocdtool", 2) expectation := "ar..." - if result != expectation { - t.Fatalf("Incorrect truncate string %q, should be %q", result, expectation) - } + require.Equalf(t, result, expectation, "Incorrect truncate string %q, should be %q", result, expectation) } func TestGetService(t *testing.T) { @@ -1040,9 +997,7 @@ func TestGetService(t *testing.T) { } result := getServer(app) expectation := "test-server" - if result != expectation { - t.Fatalf("Incorrect server %q, should be %q", result, expectation) - } + require.Equal(t, result, expectation, "Incorrect server %q, should be %q", result, expectation) }) t.Run("Name", func(t *testing.T) { app := &v1alpha1.Application{ @@ -1054,9 +1009,7 @@ func TestGetService(t *testing.T) { } result := getServer(app) expectation := "test-name" - if result != expectation { - t.Fatalf("Incorrect server name %q, should be %q", result, expectation) - } + require.Equal(t, result, expectation, "Incorrect server name %q, should be %q", result, expectation) }) } @@ -1070,17 +1023,9 @@ func TestTargetObjects(t *testing.T) { }, } objects, err := targetObjects(resources) - if err != nil { - t.Fatal("operation should finish without error") - } - - if len(objects) != 2 { - t.Fatalf("incorrect number of objects %v, should be 2", len(objects)) - } - - if objects[0].GetName() != "test-helm-guestbook" { - t.Fatalf("incorrect name %q, should be %q", objects[0].GetName(), "test-helm-guestbook") - } + require.NoError(t, err, "operation should finish without error") + require.Lenf(t, objects, 2, "incorrect number of objects %v, should be 2", len(objects)) + require.Equalf(t, "test-helm-guestbook", objects[0].GetName(), "incorrect name %q, should be %q", objects[0].GetName(), "test-helm-guestbook") } func TestTargetObjects_invalid(t *testing.T) { @@ -1107,9 +1052,7 @@ func TestPrintApplicationNames(t *testing.T) { return nil }) expectation := "test\ntest\n" - if output != expectation { - t.Fatalf("Incorrect print params output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print params output %q, should be %q", output, expectation) } func Test_unset(t *testing.T) { @@ -1762,7 +1705,7 @@ func TestCheckResourceStatus(t *testing.T) { suspended: true, health: true, degraded: true, - }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Degraded, Suspended and health status failed", func(t *testing.T) { @@ -1770,57 +1713,57 @@ func TestCheckResourceStatus(t *testing.T) { suspended: true, health: true, degraded: true, - }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.False(t, res) }) t.Run("Suspended and health status passed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: true, health: true, - }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Suspended and health status failed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: true, health: true, - }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.False(t, res) }) t.Run("Suspended passed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: true, health: false, - }, string(health.HealthStatusSuspended), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusSuspended), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Suspended failed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: true, health: false, - }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.False(t, res) }) t.Run("Health passed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: false, health: true, - }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusHealthy), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Health failed", func(t *testing.T) { res := checkResourceStatus(watchOpts{ suspended: false, health: true, - }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.False(t, res) }) t.Run("Synced passed", func(t *testing.T) { - res := checkResourceStatus(watchOpts{}, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + res := checkResourceStatus(watchOpts{}, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Synced failed", func(t *testing.T) { - res := checkResourceStatus(watchOpts{}, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeOutOfSync), &v1alpha1.Operation{}) + res := checkResourceStatus(watchOpts{}, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeOutOfSync), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Degraded passed", func(t *testing.T) { @@ -1828,7 +1771,7 @@ func TestCheckResourceStatus(t *testing.T) { suspended: false, health: false, degraded: true, - }, string(health.HealthStatusDegraded), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusDegraded), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.True(t, res) }) t.Run("Degraded failed", func(t *testing.T) { @@ -1836,7 +1779,7 @@ func TestCheckResourceStatus(t *testing.T) { suspended: false, health: false, degraded: true, - }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}) + }, string(health.HealthStatusProgressing), string(v1alpha1.SyncStatusCodeSynced), &v1alpha1.Operation{}, true) assert.False(t, res) }) } @@ -1899,9 +1842,8 @@ func Test_hasAppChanged(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := hasAppChanged(tt.args.appReq, tt.args.appRes, tt.args.upsert); got != tt.want { - t.Errorf("hasAppChanged() = %v, want %v", got, tt.want) - } + got := hasAppChanged(tt.args.appReq, tt.args.appRes, tt.args.upsert) + assert.Equalf(t, tt.want, got, "hasAppChanged() = %v, want %v", got, tt.want) }) } } diff --git a/cmd/argocd/commands/applicationset.go b/cmd/argocd/commands/applicationset.go index 4bed5aea8a992..3dcc905182258 100644 --- a/cmd/argocd/commands/applicationset.go +++ b/cmd/argocd/commands/applicationset.go @@ -13,12 +13,12 @@ import ( "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/admin" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/argoproj/argo-cd/v2/pkg/apiclient/applicationset" arogappsetv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/argo" - "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/grpc" argoio "github.com/argoproj/argo-cd/v2/util/io" @@ -93,7 +93,6 @@ func NewApplicationSetGetCommand(clientOpts *argocdclient.ClientOptions) *cobra. errors.CheckError(err) case "wide", "": printAppSetSummaryTable(appSet) - if len(appSet.Status.Conditions) > 0 { fmt.Println() w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -345,12 +344,21 @@ func NewApplicationSetDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationSetClientOrDie() defer argoio.Close(conn) var isTerminal bool = isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) - var isConfirmAll bool = false numOfApps := len(args) promptFlag := c.Flag("yes") if promptFlag.Changed && promptFlag.Value.String() == "true" { noPrompt = true } + + var ( + confirmAll = false + confirm = false + ) + + // This is for backward compatibility, + // before we showed the prompts only when condition isTerminal && !noPrompt is true + promptUtil := utils.NewPrompt(isTerminal && !noPrompt) + for _, appSetQualifiedName := range args { appSetName, appSetNs := argo.ParseFromQualifiedName(appSetQualifiedName, "") @@ -358,32 +366,17 @@ func NewApplicationSetDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob Name: appSetName, AppsetNamespace: appSetNs, } - - if isTerminal && !noPrompt { - var lowercaseAnswer string - if numOfApps == 1 { - lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appSetQualifiedName + "' and all its Applications? [y/n] ") - } else { - if !isConfirmAll { - lowercaseAnswer = cli.AskToProceedS("Are you sure you want to delete '" + appSetQualifiedName + "' and all its Applications? [y/n/A] where 'A' is to delete all specified ApplicationSets and their Applications without prompting") - if lowercaseAnswer == "a" || lowercaseAnswer == "all" { - lowercaseAnswer = "y" - isConfirmAll = true - } - } else { - lowercaseAnswer = "y" - } - } - if lowercaseAnswer == "y" || lowercaseAnswer == "yes" { - _, err := appIf.Delete(ctx, &appsetDeleteReq) - errors.CheckError(err) - fmt.Printf("applicationset '%s' deleted\n", appSetQualifiedName) - } else { - fmt.Println("The command to delete '" + appSetQualifiedName + "' was cancelled.") - } - } else { + messageForSingle := "Are you sure you want to delete '" + appSetQualifiedName + "' and all its Applications? [y/n] " + messageForAll := "Are you sure you want to delete '" + appSetQualifiedName + "' and all its Applications? [y/n/a] where 'a' is to delete all specified ApplicationSets and their Applications without prompting" + if !confirmAll { + confirm, confirmAll = promptUtil.ConfirmBaseOnCount(messageForSingle, messageForAll, numOfApps) + } + if confirm || confirmAll { _, err := appIf.Delete(ctx, &appsetDeleteReq) errors.CheckError(err) + fmt.Printf("applicationset '%s' deleted\n", appSetQualifiedName) + } else { + fmt.Println("The command to delete '" + appSetQualifiedName + "' was cancelled.") } } }, @@ -441,7 +434,6 @@ func getServerForAppSet(appSet *arogappsetv1.ApplicationSet) string { } func printAppSetSummaryTable(appSet *arogappsetv1.ApplicationSet) { - source := appSet.Spec.Template.Spec.GetSource() fmt.Printf(printOpFmtStr, "Name:", appSet.QualifiedName()) fmt.Printf(printOpFmtStr, "Project:", appSet.Spec.Template.Spec.GetProject()) fmt.Printf(printOpFmtStr, "Server:", getServerForAppSet(appSet)) @@ -451,7 +443,17 @@ func printAppSetSummaryTable(appSet *arogappsetv1.ApplicationSet) { } else { fmt.Println("Sources:") } - printAppSourceDetails(&source) + + // if no source has been defined, print the default value for a source + if len(appSet.Spec.Template.Spec.GetSources()) == 0 { + src := appSet.Spec.Template.Spec.GetSource() + printAppSourceDetails(&src) + } else { + // otherwise range over the sources and print each source details + for _, source := range appSet.Spec.Template.Spec.GetSources() { + printAppSourceDetails(&source) + } + } var ( syncPolicyStr string diff --git a/cmd/argocd/commands/applicationset_test.go b/cmd/argocd/commands/applicationset_test.go index e5034e05f9f9b..fd6f07b5d7d77 100644 --- a/cmd/argocd/commands/applicationset_test.go +++ b/cmd/argocd/commands/applicationset_test.go @@ -29,9 +29,7 @@ func TestPrintApplicationSetNames(t *testing.T) { return nil }) expectation := "test\nteam-one/test\n" - if output != expectation { - t.Fatalf("Incorrect print params output %q, should be %q", output, expectation) - } + require.Equalf(t, output, expectation, "Incorrect print params output %q, should be %q", output, expectation) } func TestPrintApplicationSetTable(t *testing.T) { @@ -147,6 +145,26 @@ func TestPrintAppSetSummaryTable(t *testing.T) { }, }, } + appsetSpecSource := baseAppSet.DeepCopy() + appsetSpecSource.Spec.Template.Spec.Source = &v1alpha1.ApplicationSource{ + RepoURL: "test1", + TargetRevision: "master1", + Path: "/test1", + } + + appsetSpecSources := baseAppSet.DeepCopy() + appsetSpecSources.Spec.Template.Spec.Sources = v1alpha1.ApplicationSources{ + { + RepoURL: "test1", + TargetRevision: "master1", + Path: "/test1", + }, + { + RepoURL: "test2", + TargetRevision: "master2", + Path: "/test2", + }, + } appsetSpecSyncPolicy := baseAppSet.DeepCopy() appsetSpecSyncPolicy.Spec.SyncPolicy = &v1alpha1.ApplicationSetSyncPolicy{ @@ -212,6 +230,37 @@ Source: - Repo: Target: SyncPolicy: Automated +`, + }, + { + name: "appset with a single source", + appSet: appsetSpecSource, + expectedOutput: `Name: app-name +Project: default +Server: +Namespace: +Source: +- Repo: test1 + Target: master1 + Path: /test1 +SyncPolicy: +`, + }, + { + name: "appset with a multiple sources", + appSet: appsetSpecSources, + expectedOutput: `Name: app-name +Project: default +Server: +Namespace: +Sources: +- Repo: test1 + Target: master1 + Path: /test1 +- Repo: test2 + Target: master2 + Path: /test2 +SyncPolicy: `, }, } { diff --git a/cmd/argocd/commands/cert.go b/cmd/argocd/commands/cert.go index 0a8204b89d9e0..d123a9ae66599 100644 --- a/cmd/argocd/commands/cert.go +++ b/cmd/argocd/commands/cert.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" certificatepkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate" appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -236,19 +237,26 @@ func NewCertRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command err := fmt.Errorf("A single wildcard is not allowed as REPOSERVER name.") errors.CheckError(err) } - certQuery = certificatepkg.RepositoryCertificateQuery{ - HostNamePattern: hostNamePattern, - CertType: certType, - CertSubType: certSubType, - } - removed, err := certIf.DeleteCertificate(ctx, &certQuery) - errors.CheckError(err) - if len(removed.Items) > 0 { - for _, cert := range removed.Items { - fmt.Printf("Removed cert for '%s' of type '%s' (subtype '%s')\n", cert.ServerName, cert.CertType, cert.CertSubType) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to remove all certificates for '%s'? [y/n]", hostNamePattern)) + if canDelete { + certQuery = certificatepkg.RepositoryCertificateQuery{ + HostNamePattern: hostNamePattern, + CertType: certType, + CertSubType: certSubType, + } + removed, err := certIf.DeleteCertificate(ctx, &certQuery) + errors.CheckError(err) + if len(removed.Items) > 0 { + for _, cert := range removed.Items { + fmt.Printf("Removed cert for '%s' of type '%s' (subtype '%s')\n", cert.ServerName, cert.CertType, cert.CertSubType) + } + } else { + fmt.Println("No certificates were removed (none matched the given pattern)") } } else { - fmt.Println("No certificates were removed (none matched the given patterns)") + fmt.Printf("The command to remove all certificates for '%s' was cancelled.\n", hostNamePattern) } }, } diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go index 729848de78634..65a3981dabac8 100644 --- a/cmd/argocd/commands/cluster.go +++ b/cmd/argocd/commands/cluster.go @@ -2,6 +2,7 @@ package commands import ( "fmt" + "net/http" "os" "regexp" "strings" @@ -106,6 +107,11 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie contextName := args[0] conf, err := getRestConfig(pathOpts, contextName) errors.CheckError(err) + if clusterOpts.ProxyUrl != "" { + u, err := argoappv1.ParseProxyUrl(clusterOpts.ProxyUrl) + errors.CheckError(err) + conf.Proxy = http.ProxyURL(u) + } clientset, err := kubernetes.NewForConfig(conf) errors.CheckError(err) managerBearerToken := "" @@ -186,11 +192,12 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie } command.PersistentFlags().StringVar(&pathOpts.LoadingRules.ExplicitPath, pathOpts.ExplicitFileFlag, pathOpts.LoadingRules.ExplicitPath, "use a particular kubeconfig file") command.Flags().BoolVar(&clusterOpts.Upsert, "upsert", false, "Override an existing cluster with the same name even if the spec differs") - command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default \"%s\" SA will be created", clusterauth.ArgoCDManagerServiceAccount)) + command.Flags().StringVar(&clusterOpts.ServiceAccount, "service-account", "", fmt.Sprintf("System namespace service account to use for kubernetes resource management. If not set then default %q SA will be created", clusterauth.ArgoCDManagerServiceAccount)) command.Flags().StringVar(&clusterOpts.SystemNamespace, "system-namespace", common.DefaultSystemNamespace, "Use different system namespace") command.Flags().BoolVarP(&skipConfirmation, "yes", "y", false, "Skip explicit confirmation") command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)") command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)") + command.Flags().StringVar(&clusterOpts.ProxyUrl, "proxy-url", "", "use proxy to connect cluster") cmdutil.AddClusterFlags(command, &clusterOpts) return command } @@ -373,6 +380,8 @@ func printClusterDetails(clusters []argoappv1.Cluster) { fmt.Printf(" Basic authentication: %v\n", cluster.Config.Username != "") fmt.Printf(" oAuth authentication: %v\n", cluster.Config.BearerToken != "") fmt.Printf(" AWS authentication: %v\n", cluster.Config.AWSAuthConfig != nil) + fmt.Printf("\nDisable compression: %v\n", cluster.Config.DisableCompression) + fmt.Printf("\nUse proxy: %v\n", cluster.Config.ProxyUrl != "") fmt.Println() } } diff --git a/cmd/argocd/commands/cluster_test.go b/cmd/argocd/commands/cluster_test.go index d0bc485ace252..311713a30fbf4 100644 --- a/cmd/argocd/commands/cluster_test.go +++ b/cmd/argocd/commands/cluster_test.go @@ -32,11 +32,12 @@ func Test_printClusterTable(t *testing.T) { Server: "my-server", Name: "my-name", Config: v1alpha1.ClusterConfig{ - Username: "my-username", - Password: "my-password", - BearerToken: "my-bearer-token", - TLSClientConfig: v1alpha1.TLSClientConfig{}, - AWSAuthConfig: nil, + Username: "my-username", + Password: "my-password", + BearerToken: "my-bearer-token", + TLSClientConfig: v1alpha1.TLSClientConfig{}, + AWSAuthConfig: nil, + DisableCompression: false, }, ConnectionState: v1alpha1.ConnectionState{ Status: "my-status", @@ -97,12 +98,12 @@ func Test_getRestConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got, err := getRestConfig(tt.args.pathOpts, tt.args.ctxName); err == nil { - require.Equal(t, tt.expected, got) - } else if tt.wantErr { - require.Equal(t, tt.expectedErr, err.Error()) + got, err := getRestConfig(tt.args.pathOpts, tt.args.ctxName) + if tt.wantErr { + require.EqualError(t, err, tt.expectedErr) } else { - t.Errorf("An unexpected error occurred during test %s:\n%s", tt.name, err.Error()) + require.NoErrorf(t, err, "An unexpected error occurred during test %s", tt.name) + require.Equal(t, tt.expected, got) } }) } diff --git a/cmd/argocd/commands/common_test.go b/cmd/argocd/commands/common_test.go index 24ab6ebcf7fd9..8a3a2446a6989 100644 --- a/cmd/argocd/commands/common_test.go +++ b/cmd/argocd/commands/common_test.go @@ -81,14 +81,14 @@ func Test_PrintResource(t *testing.T) { return err }) require.NoError(t, err) - assert.Equal(t, expectYamlSingle, str) + assert.YAMLEq(t, expectYamlSingle, str) str, err = captureOutput(func() error { err := PrintResource(testResource, "json") return err }) require.NoError(t, err) - assert.Equal(t, expectJsonSingle, str) + assert.JSONEq(t, expectJsonSingle, str) err = PrintResource(testResource, "unknown") require.Error(t, err) @@ -116,28 +116,28 @@ func Test_PrintResourceList(t *testing.T) { return err }) require.NoError(t, err) - assert.Equal(t, expectYamlList, str) + assert.YAMLEq(t, expectYamlList, str) str, err = captureOutput(func() error { err := PrintResourceList(testResource, "json", false) return err }) require.NoError(t, err) - assert.Equal(t, expectJsonList, str) + assert.JSONEq(t, expectJsonList, str) str, err = captureOutput(func() error { err := PrintResourceList(testResource2, "yaml", true) return err }) require.NoError(t, err) - assert.Equal(t, expectYamlSingle, str) + assert.YAMLEq(t, expectYamlSingle, str) str, err = captureOutput(func() error { err := PrintResourceList(testResource2, "json", true) return err }) require.NoError(t, err) - assert.Equal(t, expectJsonSingle, str) + assert.JSONEq(t, expectJsonSingle, str) err = PrintResourceList(testResource, "unknown", false) require.Error(t, err) diff --git a/cmd/argocd/commands/configure.go b/cmd/argocd/commands/configure.go new file mode 100644 index 0000000000000..15c4bef41e4ea --- /dev/null +++ b/cmd/argocd/commands/configure.go @@ -0,0 +1,44 @@ +package commands + +import ( + "fmt" + "strconv" + + "github.com/spf13/cobra" + + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/util/errors" + "github.com/argoproj/argo-cd/v2/util/localconfig" +) + +// NewConfigureCommand returns a new instance of an `argocd configure` command +func NewConfigureCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Command { + var promptsEnabled bool + + command := &cobra.Command{ + Use: "configure", + Short: "Manage local configuration", + Example: `# Enable optional interactive prompts +argocd configure --prompts-enabled +argocd configure --prompts-enabled=true + +# Disable optional interactive prompts +argocd configure --prompts-enabled=false`, + Run: func(c *cobra.Command, args []string) { + localCfg, err := localconfig.ReadLocalConfig(globalClientOpts.ConfigPath) + errors.CheckError(err) + + localCfg.PromptsEnabled = promptsEnabled + + err = localconfig.WriteLocalConfig(*localCfg, globalClientOpts.ConfigPath) + errors.CheckError(err) + + fmt.Println("Successfully updated the following configuration settings:") + fmt.Printf("prompts-enabled: %v\n", strconv.FormatBool(localCfg.PromptsEnabled)) + }, + } + + command.Flags().BoolVar(&promptsEnabled, "prompts-enabled", localconfig.GetPromptsEnabled(false), "Enable (or disable) optional interactive prompts") + + return command +} diff --git a/cmd/argocd/commands/configure_test.go b/cmd/argocd/commands/configure_test.go new file mode 100644 index 0000000000000..cb084f88abdae --- /dev/null +++ b/cmd/argocd/commands/configure_test.go @@ -0,0 +1,97 @@ +package commands + +import ( + "os" + "testing" + + argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/argoproj/argo-cd/v2/util/localconfig" +) + +func TestNewConfigureCommand_PromptsEnabled_DefaultTrue(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + localConfig, err := localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + assert.False(t, localConfig.PromptsEnabled) + + // Set `PromptsEnabled` to `true` using `argocd configure --prompts-enabled` + cmd := NewConfigureCommand(&argocdclient.ClientOptions{ConfigPath: testConfigFilePath}) + cmd.SetArgs([]string{"--prompts-enabled"}) + + err = cmd.Execute() + require.NoError(t, err) + + // Read the test config file + localConfig, err = localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + + assert.True(t, localConfig.PromptsEnabled) +} + +func TestNewConfigureCommand_PromptsEnabled_True(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + localConfig, err := localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + assert.False(t, localConfig.PromptsEnabled) + + // Set `PromptsEnabled` to `true` using `argocd configure --prompts-enabled=true` + cmd := NewConfigureCommand(&argocdclient.ClientOptions{ConfigPath: testConfigFilePath}) + cmd.SetArgs([]string{"--prompts-enabled=true"}) + + err = cmd.Execute() + require.NoError(t, err) + + // Read the test config file + localConfig, err = localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + + assert.True(t, localConfig.PromptsEnabled) +} + +func TestNewConfigureCommand_PromptsEnabled_False(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + localConfig, err := localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + assert.False(t, localConfig.PromptsEnabled) + + // Set `PromptsEnabled` to `false` using `argocd configure --prompts-enabled=false` + cmd := NewConfigureCommand(&argocdclient.ClientOptions{ConfigPath: testConfigFilePath}) + cmd.SetArgs([]string{"--prompts-enabled=false"}) + + err = cmd.Execute() + require.NoError(t, err) + + // Read the test config file + localConfig, err = localconfig.ReadLocalConfig(testConfigFilePath) + require.NoError(t, err) + + assert.False(t, localConfig.PromptsEnabled) +} diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index d68c2918f1ccb..bc50655cfaec4 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" gpgkeypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/gpgkey" appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -167,11 +168,21 @@ func NewGPGDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command if len(args) != 1 { errors.CheckError(fmt.Errorf("Missing KEYID argument")) } + + keyId := args[0] + conn, gpgIf := headless.NewClientOrDie(clientOpts, c).NewGPGKeyClientOrDie() defer argoio.Close(conn) - _, err := gpgIf.Delete(ctx, &gpgkeypkg.GnuPGPublicKeyQuery{KeyID: args[0]}) - errors.CheckError(err) - fmt.Printf("Deleted key with key ID %s\n", args[0]) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to remove '%s'? [y/n] ", keyId)) + if canDelete { + _, err := gpgIf.Delete(ctx, &gpgkeypkg.GnuPGPublicKeyQuery{KeyID: keyId}) + errors.CheckError(err) + fmt.Printf("Deleted key with key ID %s\n", keyId) + } else { + fmt.Printf("The command to delete key with key ID '%s' was cancelled.\n", keyId) + } }, } return command diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index f4d4503a9b723..40ef90b84c7e5 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -14,8 +14,10 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/runtime" + corev1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + runtimeUtil "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" cache2 "k8s.io/client-go/tools/cache" @@ -127,7 +129,7 @@ func (c *forwardRepoClientset) NewRepoServerClient() (io.Closer, repoapiclient.R } repoServerName := c.repoServerName repoServererviceLabelSelector := common.LabelKeyComponentRepoServer + "=" + common.LabelValueComponentRepoServer - repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), v1.ListOptions{LabelSelector: repoServererviceLabelSelector}) + repoServerServices, err := c.kubeClientset.CoreV1().Services(c.namespace).List(context.Background(), metaV1.ListOptions{LabelSelector: repoServererviceLabelSelector}) if err != nil { c.err = err return @@ -202,7 +204,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti } // get rid of logging error handler - runtime.ErrorHandlers = runtime.ErrorHandlers[1:] + runtimeUtil.ErrorHandlers = runtimeUtil.ErrorHandlers[1:] cli.SetLogLevel(log.ErrorLevel.String()) log.SetLevel(log.ErrorLevel) os.Setenv(v1alpha1.EnvVarFakeInClusterConfig, "true") @@ -237,7 +239,18 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti return fmt.Errorf("error creating kubernetes dynamic clientset: %w", err) } - controllerClientset, err := client.New(restConfig, client.Options{}) + scheme := runtime.NewScheme() + err = v1alpha1.AddToScheme(scheme) + if err != nil { + return fmt.Errorf("error adding argo resources to scheme: %w", err) + } + err = corev1.AddToScheme(scheme) + if err != nil { + return fmt.Errorf("error adding corev1 resources to scheme: %w", err) + } + controllerClientset, err := client.New(restConfig, client.Options{ + Scheme: scheme, + }) if err != nil { return fmt.Errorf("error creating kubernetes controller clientset: %w", err) } diff --git a/cmd/argocd/commands/logout.go b/cmd/argocd/commands/logout.go index ec532a81ed1ef..29dce709655a9 100644 --- a/cmd/argocd/commands/logout.go +++ b/cmd/argocd/commands/logout.go @@ -7,6 +7,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/localconfig" @@ -35,19 +36,26 @@ $ argocd logout log.Fatalf("Nothing to logout from") } - ok := localCfg.RemoveToken(context) - if !ok { - log.Fatalf("Context %s does not exist", context) + promptUtil := utils.NewPrompt(globalClientOpts.PromptsEnabled) + + canLogout := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to log out from '%s'?", context)) + if canLogout { + ok := localCfg.RemoveToken(context) + if !ok { + log.Fatalf("Context %s does not exist", context) + } + + err = localconfig.ValidateLocalConfig(*localCfg) + if err != nil { + log.Fatalf("Error in logging out: %s", err) + } + err = localconfig.WriteLocalConfig(*localCfg, globalClientOpts.ConfigPath) + errors.CheckError(err) + + fmt.Printf("Logged out from '%s'\n", context) + } else { + log.Infof("Logout from '%s' cancelled", context) } - - err = localconfig.ValidateLocalConfig(*localCfg) - if err != nil { - log.Fatalf("Error in logging out: %s", err) - } - err = localconfig.WriteLocalConfig(*localCfg, globalClientOpts.ConfigPath) - errors.CheckError(err) - - fmt.Printf("Logged out from '%s'\n", context) }, } return command diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go index 827af5e536c33..b3dc9498d6b84 100644 --- a/cmd/argocd/commands/project.go +++ b/cmd/argocd/commands/project.go @@ -18,6 +18,7 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" @@ -781,11 +782,19 @@ func NewProjectDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm c.HelpFunc()(c, args) os.Exit(1) } + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() defer argoio.Close(conn) for _, name := range args { - _, err := projIf.Delete(ctx, &projectpkg.ProjectQuery{Name: name}) - errors.CheckError(err) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete %s? [y/n]", name)) + if canDelete { + _, err := projIf.Delete(ctx, &projectpkg.ProjectQuery{Name: name}) + errors.CheckError(err) + } else { + fmt.Printf("The command to delete %s was cancelled.\n", name) + } } }, } diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 023bf18fba700..a0da6793fa7e6 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -12,6 +12,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -169,8 +170,15 @@ ID ISSUED-AT EXPIRES-AT } role.Policies[duplicateIndex] = role.Policies[len(role.Policies)-1] proj.Spec.Roles[roleIndex].Policies = role.Policies[:len(role.Policies)-1] - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete '%s' policy? [y/n]", policyToRemove)) + if canDelete { + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + } else { + fmt.Printf("The command to delete policy '%s' was cancelled.\n", policyToRemove) + } }, } addPolicyFlags(command, &opts) @@ -237,6 +245,8 @@ func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() defer io.Close(conn) + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) errors.CheckError(err) @@ -248,9 +258,14 @@ func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. proj.Spec.Roles[index] = proj.Spec.Roles[len(proj.Spec.Roles)-1] proj.Spec.Roles = proj.Spec.Roles[:len(proj.Spec.Roles)-1] - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) - fmt.Printf("Role '%s' deleted\n", roleName) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete '%s' role? [y/n]", roleName)) + if canDelete { + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + fmt.Printf("Role '%s' deleted\n", roleName) + } else { + fmt.Printf("The command to delete role '%s' was cancelled.\n", roleName) + } }, } return command @@ -437,14 +452,22 @@ $ argocd proj role delete-token test-project test-role 1696769937 } projName := args[0] roleName := args[1] - issuedAt, err := strconv.ParseInt(args[2], 10, 64) + tokenId := args[2] + issuedAt, err := strconv.ParseInt(tokenId, 10, 64) errors.CheckError(err) + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() defer io.Close(conn) - _, err = projIf.DeleteToken(ctx, &projectpkg.ProjectTokenDeleteRequest{Project: projName, Role: roleName, Iat: issuedAt}) - errors.CheckError(err) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete '%s' project token? [y/n]", tokenId)) + if canDelete { + _, err = projIf.DeleteToken(ctx, &projectpkg.ProjectTokenDeleteRequest{Project: projName, Role: roleName, Iat: issuedAt}) + errors.CheckError(err) + } else { + fmt.Printf("The command to delete project token '%s' was cancelled.\n", tokenId) + } }, } return command @@ -621,9 +644,18 @@ func NewProjectRoleRemoveGroupCommand(clientOpts *argocdclient.ClientOptions) *c fmt.Printf("Group '%s' not present in role '%s'\n", groupName, roleName) return } - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) - fmt.Printf("Group '%s' removed from role '%s'\n", groupName, roleName) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to remove '%s' group from role '%s'? [y/n]", groupName, roleName)) + + if canDelete { + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + fmt.Printf("Group '%s' removed from role '%s'\n", groupName, roleName) + } else { + fmt.Printf("The command to remove group '%s' from role '%s' was cancelled.\n", groupName, roleName) + } }, } return command diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index d824222306419..589064b240351 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" projectpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/project" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -235,8 +236,14 @@ argocd proj windows delete new-project 1`, err = proj.Spec.DeleteWindow(id) errors.CheckError(err) - _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) - errors.CheckError(err) + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + canDelete := promptUtil.Confirm("Are you sure you want to delete sync window? [y/n]") + if canDelete { + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + } else { + fmt.Printf("The command to delete the sync window was cancelled\n") + } }, } return command @@ -352,9 +359,10 @@ func printSyncWindows(proj *v1alpha1.AppProject) { fmt.Fprintf(w, fmtStr, headers...) if proj.Spec.SyncWindows.HasWindows() { for i, window := range proj.Spec.SyncWindows { + isActive, _ := window.Active() vals := []interface{}{ strconv.Itoa(i), - formatBoolOutput(window.Active()), + formatBoolOutput(isActive), window.Kind, window.Schedule, window.Duration, diff --git a/cmd/argocd/commands/repo.go b/cmd/argocd/commands/repo.go index f58204ea76c3a..3aba1b2e65513 100644 --- a/cmd/argocd/commands/repo.go +++ b/cmd/argocd/commands/repo.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" repositorypkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" @@ -254,10 +255,17 @@ func NewRepoRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoClientOrDie() defer io.Close(conn) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) for _, repoURL := range args { - _, err := repoIf.DeleteRepository(ctx, &repositorypkg.RepoQuery{Repo: repoURL, AppProject: project}) - errors.CheckError(err) - fmt.Printf("Repository '%s' removed\n", repoURL) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to delete repository '%s'? [y/n]", repoURL)) + if canDelete { + _, err := repoIf.DeleteRepository(ctx, &repositorypkg.RepoQuery{Repo: repoURL, AppProject: project}) + errors.CheckError(err) + fmt.Printf("Repository '%s' removed\n", repoURL) + } else { + fmt.Printf("The command to delete '%s' was cancelled.\n", repoURL) + } } }, } diff --git a/cmd/argocd/commands/repocreds.go b/cmd/argocd/commands/repocreds.go index 21ebca795cdfb..215895d5fcc13 100644 --- a/cmd/argocd/commands/repocreds.go +++ b/cmd/argocd/commands/repocreds.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/utils" "github.com/argoproj/argo-cd/v2/common" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds" @@ -209,10 +210,18 @@ func NewRepoCredsRemoveCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } conn, repoIf := headless.NewClientOrDie(clientOpts, c).NewRepoCredsClientOrDie() defer io.Close(conn) + + promptUtil := utils.NewPrompt(clientOpts.PromptsEnabled) + for _, repoURL := range args { - _, err := repoIf.DeleteRepositoryCredentials(ctx, &repocredspkg.RepoCredsDeleteRequest{Url: repoURL}) - errors.CheckError(err) - fmt.Printf("Repository credentials for '%s' removed\n", repoURL) + canDelete := promptUtil.Confirm(fmt.Sprintf("Are you sure you want to remove '%s'? [y/n] ", repoURL)) + if canDelete { + _, err := repoIf.DeleteRepositoryCredentials(ctx, &repocredspkg.RepoCredsDeleteRequest{Url: repoURL}) + errors.CheckError(err) + fmt.Printf("Repository credentials for '%s' removed\n", repoURL) + } else { + fmt.Printf("The command to remove '%s' was cancelled.\n", repoURL) + } } }, } diff --git a/cmd/argocd/commands/root.go b/cmd/argocd/commands/root.go index 4386b8febd6c4..c2d81a16600f9 100644 --- a/cmd/argocd/commands/root.go +++ b/cmd/argocd/commands/root.go @@ -60,6 +60,7 @@ func NewCommand() *cobra.Command { command.AddCommand(initialize.InitCommand(NewCertCommand(&clientOpts))) command.AddCommand(initialize.InitCommand(NewGPGCommand(&clientOpts))) command.AddCommand(admin.NewAdminCommand(&clientOpts)) + command.AddCommand(initialize.InitCommand(NewConfigureCommand(&clientOpts))) defaultLocalConfigPath, err := localconfig.DefaultLocalConfigPath() errors.CheckError(err) @@ -86,6 +87,7 @@ func NewCommand() *cobra.Command { command.PersistentFlags().StringVar(&clientOpts.RedisHaProxyName, "redis-haproxy-name", env.StringFromEnv(common.EnvRedisHaProxyName, common.DefaultRedisHaProxyName), fmt.Sprintf("Name of the Redis HA Proxy; set this or the %s environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart", common.EnvRedisHaProxyName)) command.PersistentFlags().StringVar(&clientOpts.RedisName, "redis-name", env.StringFromEnv(common.EnvRedisName, common.DefaultRedisName), fmt.Sprintf("Name of the Redis deployment; set this or the %s environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart", common.EnvRedisName)) command.PersistentFlags().StringVar(&clientOpts.RepoServerName, "repo-server-name", env.StringFromEnv(common.EnvRepoServerName, common.DefaultRepoServerName), fmt.Sprintf("Name of the Argo CD Repo server; set this or the %s environment variable when the server's name label differs from the default, for example when installing via the Helm chart", common.EnvRepoServerName)) + command.PersistentFlags().BoolVar(&clientOpts.PromptsEnabled, "prompts-enabled", localconfig.GetPromptsEnabled(true), "Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default.") clientOpts.KubeOverrides = &clientcmd.ConfigOverrides{} command.PersistentFlags().StringVar(&clientOpts.KubeOverrides.CurrentContext, "kube-context", "", "Directs the command to the given kube-context") diff --git a/cmd/argocd/commands/tree_test.go b/cmd/argocd/commands/tree_test.go index 70f7a86ae759e..c0d2129fed132 100644 --- a/cmd/argocd/commands/tree_test.go +++ b/cmd/argocd/commands/tree_test.go @@ -6,6 +6,7 @@ import ( "text/tabwriter" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -38,9 +39,7 @@ func TestTreeViewAppGet(t *testing.T) { buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) treeViewAppGet("", objs, childMapping, parent, stateMap, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() assert.Contains(t, output, "ReplicaSet") assert.Contains(t, output, "Rollout") @@ -77,9 +76,7 @@ func TestTreeViewDetailedAppGet(t *testing.T) { buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) detailedTreeViewAppGet("", objs, childMapping, parent, stateMap, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() @@ -119,9 +116,7 @@ func TestTreeViewAppResources(t *testing.T) { orphanParent := orphan treeViewAppResourcesOrphaned("", objsOrphan, orphanchildMapping, orphanParent, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() assert.Contains(t, output, "ReplicaSet") @@ -159,9 +154,7 @@ func TestTreeViewDetailedAppResources(t *testing.T) { orphanchildMapping := make(map[string][]string) orphanParent := orphan detailedTreeViewAppResourcesOrphaned("", objsOrphan, orphanchildMapping, orphanParent, w) - if err := w.Flush(); err != nil { - t.Fatal(err) - } + require.NoError(t, w.Flush()) output := buf.String() assert.Contains(t, output, "ReplicaSet") diff --git a/cmd/argocd/commands/utils/prompt.go b/cmd/argocd/commands/utils/prompt.go new file mode 100644 index 0000000000000..2aa016ef1e0ff --- /dev/null +++ b/cmd/argocd/commands/utils/prompt.go @@ -0,0 +1,60 @@ +package utils + +import ( + "github.com/argoproj/argo-cd/v2/util/cli" +) + +type Prompt struct { + enabled bool +} + +func NewPrompt(promptsEnabled bool) *Prompt { + return &Prompt{ + enabled: promptsEnabled, + } +} + +func (p *Prompt) Confirm(message string) bool { + if !p.enabled { + return true + } + + return cli.AskToProceed(message) +} + +// ConfirmAll asks the user to confirm an action. If prompts are disabled, it will return true. +// support y/n and A, which means all +// return if confirm and if all +func (p *Prompt) ConfirmAll(message string) (bool, bool) { + if !p.enabled { + return true, true + } + + result := cli.AskToProceedS(message) + + if result == "a" { + return true, true + } + + if result == "y" { + return true, false + } + + return false, false +} + +func (p *Prompt) ConfirmBaseOnCount(messageForSingle string, messageForArray string, count int) (bool, bool) { + if !p.enabled { + return true, true + } + + if count == 0 { + return true, true + } + + if count == 1 { + return p.Confirm(messageForSingle), true + } + + return p.ConfirmAll(messageForArray) +} diff --git a/cmd/argocd/commands/utils/prompt_test.go b/cmd/argocd/commands/utils/prompt_test.go new file mode 100644 index 0000000000000..a9c8b89cfa799 --- /dev/null +++ b/cmd/argocd/commands/utils/prompt_test.go @@ -0,0 +1,118 @@ +package utils + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewPrompt_PromptsEnabled_True(t *testing.T) { + prompt := NewPrompt(true) + assert.True(t, prompt.enabled) +} + +func TestNewPrompt_PromptsEnabled_False(t *testing.T) { + prompt := NewPrompt(false) + assert.False(t, prompt.enabled) +} + +func TestConfirm_PromptsEnabled_False(t *testing.T) { + prompt := NewPrompt(false) + assert.True(t, prompt.Confirm("Are you sure you want to run this command? (y/n) ")) +} + +// Returns true, true when prompt is disabled +func TestConfirmAllPromptDisabled(t *testing.T) { + p := &Prompt{enabled: false} + result1, result2 := p.ConfirmAll("Proceed?") + assert.True(t, result1) + assert.True(t, result2) +} + +func TestConfirmBaseOnCountPromptDisabled(t *testing.T) { + p := &Prompt{enabled: false} + result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 2) + assert.True(t, result1) + assert.True(t, result2) +} + +func TestConfirmBaseOnCountZeroApps(t *testing.T) { + p := &Prompt{enabled: true} + result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 0) + assert.True(t, result1) + assert.True(t, result2) +} + +func TestConfirmPrompt(t *testing.T) { + cases := []struct { + input string + output bool + }{ + {"y\n", true}, + {"n\n", false}, + } + + origStdin := os.Stdin + + for _, c := range cases { + tmpFile, err := writeToStdin(c.input) + require.NoError(t, err) + p := &Prompt{enabled: true} + result := p.Confirm("Are you sure you want to run this command? (y/n) \n") + assert.Equal(t, c.output, result) + os.Remove(tmpFile.Name()) + _ = tmpFile.Close() + } + + os.Stdin = origStdin +} + +func TestConfirmAllPrompt(t *testing.T) { + cases := []struct { + input string + confirm bool + confirmAll bool + }{ + {"y\n", true, false}, + {"n\n", false, false}, + {"a\n", true, true}, + } + + origStdin := os.Stdin + + for _, c := range cases { + tmpFile, err := writeToStdin(c.input) + require.NoError(t, err) + p := &Prompt{enabled: true} + confirm, confirmAll := p.ConfirmAll("Are you sure you want to run this command? (y/n) \n") + assert.Equal(t, c.confirm, confirm) + assert.Equal(t, c.confirmAll, confirmAll) + os.Remove(tmpFile.Name()) + _ = tmpFile.Close() + } + + os.Stdin = origStdin +} + +func writeToStdin(msg string) (*os.File, error) { + tmpFile, err := os.CreateTemp("", "test-input") + if err != nil { + return nil, err + } + + // Write the input to the temporary file + if _, err := tmpFile.WriteString(msg); err != nil { + return nil, err + } + + // Seek to the beginning of the file so it can be read from the start + if _, err := tmpFile.Seek(0, 0); err != nil { + return nil, err + } + + os.Stdin = tmpFile + + return tmpFile, nil +} diff --git a/cmd/argocd/commands/version_test.go b/cmd/argocd/commands/version_test.go index 54bfb21b18b61..fb85a491ec3bd 100644 --- a/cmd/argocd/commands/version_test.go +++ b/cmd/argocd/commands/version_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" @@ -15,12 +16,8 @@ func TestShortVersionClient(t *testing.T) { cmd := NewVersionCmd(&argocdclient.ClientOptions{}, nil) cmd.SetOut(buf) cmd.SetArgs([]string{"version", "--short", "--client"}) - err := cmd.Execute() - if err != nil { - t.Fatal("Failed to execute short version command") - } - output := buf.String() - assert.Equal(t, "argocd: v99.99.99+unknown\n", output) + require.NoError(t, cmd.Execute(), "Failed to execute short version command") + assert.Equal(t, "argocd: v99.99.99+unknown\n", buf.String()) } func TestShortVersion(t *testing.T) { @@ -29,10 +26,6 @@ func TestShortVersion(t *testing.T) { cmd := NewVersionCmd(&argocdclient.ClientOptions{}, serverVersion) cmd.SetOut(buf) cmd.SetArgs([]string{"argocd", "version", "--short"}) - err := cmd.Execute() - if err != nil { - t.Fatal("Failed to execute short version command") - } - output := buf.String() - assert.Equal(t, "argocd: v99.99.99+unknown\nargocd-server: v99.99.99+unknown\n", output) + require.NoError(t, cmd.Execute(), "Failed to execute short version command") + assert.Equal(t, "argocd: v99.99.99+unknown\nargocd-server: v99.99.99+unknown\n", buf.String()) } diff --git a/cmd/main.go b/cmd/main.go index e6c94c40f7c85..92eb27049c9fc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,13 +4,14 @@ import ( "os" "path/filepath" - "github.com/spf13/cobra" + "github.com/argoproj/argo-cd/v2/cmd/util" - _ "go.uber.org/automaxprocs" + "github.com/spf13/cobra" appcontroller "github.com/argoproj/argo-cd/v2/cmd/argocd-application-controller/commands" applicationset "github.com/argoproj/argo-cd/v2/cmd/argocd-applicationset-controller/commands" cmpserver "github.com/argoproj/argo-cd/v2/cmd/argocd-cmp-server/commands" + commitserver "github.com/argoproj/argo-cd/v2/cmd/argocd-commit-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" k8sauth "github.com/argoproj/argo-cd/v2/cmd/argocd-k8s-auth/commands" @@ -31,9 +32,12 @@ func main() { if val := os.Getenv(binaryNameEnv); val != "" { binaryName = val } + + isCLI := false switch binaryName { case "argocd", "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe": command = cli.NewCommand() + isCLI = true case "argocd-server": command = apiserver.NewCommand() case "argocd-application-controller": @@ -42,19 +46,26 @@ func main() { command = reposerver.NewCommand() case "argocd-cmp-server": command = cmpserver.NewCommand() + isCLI = true + case "argocd-commit-server": + command = commitserver.NewCommand() case "argocd-dex": command = dex.NewCommand() case "argocd-notifications": command = notification.NewCommand() case "argocd-git-ask-pass": command = gitaskpass.NewCommand() + isCLI = true case "argocd-applicationset-controller": command = applicationset.NewCommand() case "argocd-k8s-auth": command = k8sauth.NewCommand() + isCLI = true default: command = cli.NewCommand() + isCLI = true } + util.SetAutoMaxProcs(isCLI) if err := command.Execute(); err != nil { os.Exit(1) diff --git a/cmd/util/app.go b/cmd/util/app.go index 56b48fee82131..e66c03f4e9374 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -9,6 +9,8 @@ import ( "strings" "time" + "go.uber.org/automaxprocs/maxprocs" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -48,6 +50,8 @@ type AppOptions struct { helmVersion string helmPassCredentials bool helmSkipCrds bool + helmSkipSchemaValidation bool + helmSkipTests bool helmNamespace string helmKubeVersion string helmApiVersions []string @@ -86,6 +90,26 @@ type AppOptions struct { retryBackoffMaxDuration time.Duration retryBackoffFactor int64 ref string + SourceName string + drySourceRepo string + drySourceRevision string + drySourcePath string + syncSourceBranch string + syncSourcePath string + hydrateToBranch string +} + +// SetAutoMaxProcs sets the GOMAXPROCS value based on the binary name. +// It suppresses logs for CLI binaries and logs the setting for services. +func SetAutoMaxProcs(isCLI bool) { + if isCLI { + _, _ = maxprocs.Set() // Intentionally ignore errors for CLI binaries + } else { + _, err := maxprocs.Set(maxprocs.Logger(log.Infof)) + if err != nil { + log.Errorf("Error setting GOMAXPROCS: %v", err) + } + } } func AddAppFlags(command *cobra.Command, opts *AppOptions) { @@ -94,6 +118,12 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringVar(&opts.chart, "helm-chart", "", "Helm Chart name") command.Flags().StringVar(&opts.env, "env", "", "Application environment to monitor") command.Flags().StringVar(&opts.revision, "revision", "", "The tracking source branch, tag, commit or Helm chart version the application will sync to") + command.Flags().StringVar(&opts.drySourceRepo, "dry-source-repo", "", "Repository URL of the app dry source") + command.Flags().StringVar(&opts.drySourceRevision, "dry-source-revision", "", "Revision of the app dry source") + command.Flags().StringVar(&opts.drySourcePath, "dry-source-path", "", "Path in repository to the app directory for the dry source") + command.Flags().StringVar(&opts.syncSourceBranch, "sync-source-branch", "", "The branch from which the app will sync") + command.Flags().StringVar(&opts.syncSourcePath, "sync-source-path", "", "The path in the repository from which the app will sync") + command.Flags().StringVar(&opts.hydrateToBranch, "hydrate-to-branch", "", "The branch to hydrate the app to") command.Flags().IntVar(&opts.revisionHistoryLimit, "revision-history-limit", argoappv1.RevisionHistoryLimit, "How many items to keep in revision history") command.Flags().StringVar(&opts.destServer, "dest-server", "", "K8s cluster URL (e.g. https://kubernetes.default.svc)") command.Flags().StringVar(&opts.destName, "dest-name", "", "K8s cluster Name (e.g. minikube)") @@ -109,6 +139,8 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringArrayVar(&opts.helmSetStrings, "helm-set-string", []string{}, "Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2)") command.Flags().StringArrayVar(&opts.helmSetFiles, "helm-set-file", []string{}, "Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2)") command.Flags().BoolVar(&opts.helmSkipCrds, "helm-skip-crds", false, "Skip helm crd installation step") + command.Flags().BoolVar(&opts.helmSkipSchemaValidation, "helm-skip-schema-validation", false, "Skip helm schema validation step") + command.Flags().BoolVar(&opts.helmSkipTests, "helm-skip-tests", false, "Skip helm test manifests installation step") command.Flags().StringVar(&opts.helmNamespace, "helm-namespace", "", "Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace") command.Flags().StringVar(&opts.helmKubeVersion, "helm-kube-version", "", "Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster") command.Flags().StringArrayVar(&opts.helmApiVersions, "helm-api-versions", []string{}, "Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster") @@ -147,6 +179,7 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().DurationVar(&opts.retryBackoffMaxDuration, "sync-retry-backoff-max-duration", argoappv1.DefaultSyncRetryMaxDuration, "Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h)") command.Flags().Int64Var(&opts.retryBackoffFactor, "sync-retry-backoff-factor", argoappv1.DefaultSyncRetryFactor, "Factor multiplies the base duration after each failed sync retry") command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field") + command.Flags().StringVar(&opts.SourceName, "source-name", "", "Name of the source from the list of sources of the app.") } func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, sourcePosition int) int { @@ -154,21 +187,27 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap if flags == nil { return visited } - source := spec.GetSourcePtrByPosition(sourcePosition) - if source == nil { - source = &argoappv1.ApplicationSource{} - } - source, visited = ConstructSource(source, *appOpts, flags) - if spec.HasMultipleSources() { - if sourcePosition == 0 { - spec.Sources[sourcePosition] = *source - } else if sourcePosition > 0 { - spec.Sources[sourcePosition-1] = *source + var h *argoappv1.SourceHydrator + h, hasHydratorFlag := constructSourceHydrator(spec.SourceHydrator, *appOpts, flags) + if hasHydratorFlag { + spec.SourceHydrator = h + } else { + source := spec.GetSourcePtrByPosition(sourcePosition) + if source == nil { + source = &argoappv1.ApplicationSource{} + } + source, visited = ConstructSource(source, *appOpts, flags) + if spec.HasMultipleSources() { + if sourcePosition == 0 { + spec.Sources[sourcePosition] = *source + } else if sourcePosition > 0 { + spec.Sources[sourcePosition-1] = *source + } else { + spec.Sources = append(spec.Sources, *source) + } } else { - spec.Sources = append(spec.Sources, *source) + spec.Source = source } - } else { - spec.Source = source } flags.Visit(func(f *pflag.Flag) { visited++ @@ -358,6 +397,8 @@ type helmOpts struct { helmSetFiles []string passCredentials bool skipCrds bool + skipSchemaValidation bool + skipTests bool namespace string kubeVersion string apiVersions []string @@ -391,6 +432,12 @@ func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) { if opts.skipCrds { src.Helm.SkipCrds = opts.skipCrds } + if opts.skipSchemaValidation { + src.Helm.SkipSchemaValidation = opts.skipSchemaValidation + } + if opts.skipTests { + src.Helm.SkipTests = opts.skipTests + } if opts.namespace != "" { src.Helm.Namespace = opts.namespace } @@ -563,9 +610,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, Name: appName, Namespace: appNs, }, - Spec: argoappv1.ApplicationSpec{ - Source: &argoappv1.ApplicationSource{}, - }, + Spec: argoappv1.ApplicationSpec{}, } SetAppSpecOptions(flags, &app.Spec, &appOpts, 0) SetParameterOverrides(app, appOpts.Parameters, 0) @@ -658,6 +703,10 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setHelmOpt(source, helmOpts{helmSetFiles: appOpts.helmSetFiles}) case "helm-skip-crds": setHelmOpt(source, helmOpts{skipCrds: appOpts.helmSkipCrds}) + case "helm-skip-schema-validation": + setHelmOpt(source, helmOpts{skipSchemaValidation: appOpts.helmSkipSchemaValidation}) + case "helm-skip-tests": + setHelmOpt(source, helmOpts{skipTests: appOpts.helmSkipTests}) case "helm-namespace": setHelmOpt(source, helmOpts{namespace: appOpts.helmNamespace}) case "helm-kube-version": @@ -728,11 +777,54 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setPluginOptEnvs(source, appOpts.pluginEnvs) case "ref": source.Ref = appOpts.ref + case "source-name": + source.Name = appOpts.SourceName } }) return source, visited } +// constructSourceHydrator constructs a source hydrator from the command line flags. It returns the modified source +// hydrator and a boolean indicating if any hydrator flags were set. We return instead of just modifying the source +// hydrator in place because the given hydrator `h` might be nil. In that case, we need to create a new source hydrator +// and return it. +func constructSourceHydrator(h *argoappv1.SourceHydrator, appOpts AppOptions, flags *pflag.FlagSet) (*argoappv1.SourceHydrator, bool) { + hasHydratorFlag := false + ensureNotNil := func(notEmpty bool) { + hasHydratorFlag = true + if notEmpty && h == nil { + h = &argoappv1.SourceHydrator{} + } + } + flags.Visit(func(f *pflag.Flag) { + switch f.Name { + case "dry-source-repo": + ensureNotNil(appOpts.drySourceRepo != "") + h.DrySource.RepoURL = appOpts.drySourceRepo + case "dry-source-path": + ensureNotNil(appOpts.drySourcePath != "") + h.DrySource.Path = appOpts.drySourcePath + case "dry-source-revision": + ensureNotNil(appOpts.drySourceRevision != "") + h.DrySource.TargetRevision = appOpts.drySourceRevision + case "sync-source-branch": + ensureNotNil(appOpts.syncSourceBranch != "") + h.SyncSource.TargetBranch = appOpts.syncSourceBranch + case "sync-source-path": + ensureNotNil(appOpts.syncSourcePath != "") + h.SyncSource.Path = appOpts.syncSourcePath + case "hydrate-to-branch": + ensureNotNil(appOpts.hydrateToBranch != "") + if appOpts.hydrateToBranch == "" { + h.HydrateTo = nil + } else { + h.HydrateTo = &argoappv1.HydrateTo{TargetBranch: appOpts.hydrateToBranch} + } + } + }) + return h, hasHydratorFlag +} + func mergeLabels(app *argoappv1.Application, labels []string) { mapLabels, err := label.Parse(labels) errors.CheckError(err) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index 595b9be46563e..46b411503366b 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -1,10 +1,11 @@ package util import ( + "bytes" + "log" "os" "testing" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -65,6 +66,16 @@ func Test_setHelmOpt(t *testing.T) { setHelmOpt(&src, helmOpts{skipCrds: true}) assert.True(t, src.Helm.SkipCrds) }) + t.Run("HelmSkipSchemaValidation", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setHelmOpt(&src, helmOpts{skipSchemaValidation: true}) + assert.True(t, src.Helm.SkipSchemaValidation) + }) + t.Run("HelmSkipTests", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setHelmOpt(&src, helmOpts{skipTests: true}) + assert.True(t, src.Helm.SkipTests) + }) t.Run("HelmNamespace", func(t *testing.T) { src := v1alpha1.ApplicationSource{} setHelmOpt(&src, helmOpts{namespace: "custom-namespace"}) @@ -284,6 +295,28 @@ func Test_setAppSpecOptions(t *testing.T) { require.NoError(t, f.SetFlag("helm-api-versions", "v2")) assert.Equal(t, []string{"v1", "v2"}, f.spec.Source.Helm.APIVersions) }) + t.Run("source hydrator", func(t *testing.T) { + require.NoError(t, f.SetFlag("dry-source-repo", "https://github.com/argoproj/argocd-example-apps")) + assert.Equal(t, "https://github.com/argoproj/argocd-example-apps", f.spec.SourceHydrator.DrySource.RepoURL) + + require.NoError(t, f.SetFlag("dry-source-path", "apps")) + assert.Equal(t, "apps", f.spec.SourceHydrator.DrySource.Path) + + require.NoError(t, f.SetFlag("dry-source-revision", "HEAD")) + assert.Equal(t, "HEAD", f.spec.SourceHydrator.DrySource.TargetRevision) + + require.NoError(t, f.SetFlag("sync-source-branch", "env/test")) + assert.Equal(t, "env/test", f.spec.SourceHydrator.SyncSource.TargetBranch) + + require.NoError(t, f.SetFlag("sync-source-path", "apps")) + assert.Equal(t, "apps", f.spec.SourceHydrator.SyncSource.Path) + + require.NoError(t, f.SetFlag("hydrate-to-branch", "env/test-next")) + assert.Equal(t, "env/test-next", f.spec.SourceHydrator.HydrateTo.TargetBranch) + + require.NoError(t, f.SetFlag("hydrate-to-branch", "")) + assert.Nil(t, f.spec.SourceHydrator.HydrateTo) + }) } func newMultiSourceAppOptionsFixture() *appOptionsFixture { @@ -529,3 +562,27 @@ func TestFilterResources(t *testing.T) { assert.Nil(t, filteredResources) }) } + +func TestSetAutoMaxProcs(t *testing.T) { + t.Run("CLI mode ignores errors", func(t *testing.T) { + logBuffer := &bytes.Buffer{} + oldLogger := log.Default() + log.SetOutput(logBuffer) + defer log.SetOutput(oldLogger.Writer()) + + SetAutoMaxProcs(true) + + assert.Empty(t, logBuffer.String(), "Expected no log output when isCLI is true") + }) + + t.Run("Non-CLI mode logs error on failure", func(t *testing.T) { + logBuffer := &bytes.Buffer{} + oldLogger := log.Default() + log.SetOutput(logBuffer) + defer log.SetOutput(oldLogger.Writer()) + + SetAutoMaxProcs(false) + + assert.NotContains(t, logBuffer.String(), "Error setting GOMAXPROCS", "Unexpected log output detected") + }) +} diff --git a/cmd/util/cluster.go b/cmd/util/cluster.go index e56048660d83f..ab4e4816cf1d7 100644 --- a/cmd/util/cluster.go +++ b/cmd/util/cluster.go @@ -100,11 +100,18 @@ func NewCluster(name string, namespaces []string, clusterResources bool, conf *r TLSClientConfig: tlsClientConfig, AWSAuthConfig: awsAuthConf, ExecProviderConfig: execProviderConf, + DisableCompression: conf.DisableCompression, }, Labels: labels, Annotations: annotations, } - + // it's a tradeoff to get proxy url from rest config + // more detail: https://github.com/kubernetes/kubernetes/pull/81443 + if conf.Proxy != nil { + if url, err := conf.Proxy(nil); err == nil { + clst.Config.ProxyUrl = url.String() + } + } // Bearer token will preferentially be used for auth if present, // Even in presence of key/cert credentials // So set bearer token only if the key/cert data is absent @@ -158,6 +165,8 @@ type ClusterOptions struct { ExecProviderAPIVersion string ExecProviderInstallHint string ClusterEndpoint string + DisableCompression bool + ProxyUrl string } // InClusterEndpoint returns true if ArgoCD should reference the in-cluster @@ -182,4 +191,5 @@ func AddClusterFlags(command *cobra.Command, opts *ClusterOptions) { command.Flags().StringVar(&opts.ExecProviderAPIVersion, "exec-command-api-version", "", "Preferred input version of the ExecInfo for the --exec-command executable") command.Flags().StringVar(&opts.ExecProviderInstallHint, "exec-command-install-hint", "", "Text shown to the user when the --exec-command executable doesn't seem to be present") command.Flags().StringVar(&opts.ClusterEndpoint, "cluster-endpoint", "", "Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'.") + command.Flags().BoolVar(&opts.DisableCompression, "disable-compression", false, "Bypasses automatic GZip compression requests to the server") } diff --git a/cmd/util/cluster_test.go b/cmd/util/cluster_test.go index 24b46765ca686..12ed3fe5cc3ad 100644 --- a/cmd/util/cluster_test.go +++ b/cmd/util/cluster_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -37,6 +38,7 @@ func Test_newCluster(t *testing.T) { assert.Equal(t, "", clusterWithData.Config.BearerToken) assert.Equal(t, labels, clusterWithData.Labels) assert.Equal(t, annotations, clusterWithData.Annotations) + assert.False(t, clusterWithData.Config.DisableCompression) clusterWithFiles := NewCluster("test-cluster", []string{"test-namespace"}, false, &rest.Config{ TLSClientConfig: rest.TLSClientConfig{ @@ -73,6 +75,20 @@ func Test_newCluster(t *testing.T) { assert.Equal(t, "test-bearer-token", clusterWithBearerToken.Config.BearerToken) assert.Nil(t, clusterWithBearerToken.Labels) assert.Nil(t, clusterWithBearerToken.Annotations) + + clusterWithDisableCompression := NewCluster("test-cluster", []string{"test-namespace"}, false, &rest.Config{ + TLSClientConfig: rest.TLSClientConfig{ + Insecure: false, + ServerName: "test-endpoint.example.com", + CAData: []byte("test-ca-data"), + }, + DisableCompression: true, + Host: "test-endpoint.example.com", + }, "test-bearer-token", + &v1alpha1.AWSAuthConfig{}, + &v1alpha1.ExecProviderConfig{}, labels, annotations) + + assert.True(t, clusterWithDisableCompression.Config.DisableCompression) } func TestGetKubePublicEndpoint(t *testing.T) { @@ -146,17 +162,14 @@ func TestGetKubePublicEndpoint(t *testing.T) { if tc.clusterInfo != nil { objects = append(objects, tc.clusterInfo) } - clientset := fake.NewSimpleClientset(objects...) + clientset := fake.NewClientset(objects...) endpoint, err := GetKubePublicEndpoint(clientset) - if err != nil && !tc.expectError { - t.Fatalf("unexpected error: %v", err) - } - if err == nil && tc.expectError { - t.Error("expected error to be returned, received none") - } - if endpoint != tc.expectedEndpoint { - t.Errorf("expected endpoint %s, got %s", tc.expectedEndpoint, endpoint) + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) } + require.Equalf(t, tc.expectedEndpoint, endpoint, "expected endpoint %s, got %s", tc.expectedEndpoint, endpoint) }) } } diff --git a/cmd/util/project.go b/cmd/util/project.go index b0a82883dc0bb..63dff2018c975 100644 --- a/cmd/util/project.go +++ b/cmd/util/project.go @@ -48,6 +48,8 @@ func AddProjFlags(command *cobra.Command, opts *ProjectOpts) { command.Flags().StringArrayVar(&opts.allowedNamespacedResources, "allow-namespaced-resource", []string{}, "List of allowed namespaced resources") command.Flags().StringArrayVar(&opts.deniedNamespacedResources, "deny-namespaced-resource", []string{}, "List of denied namespaced resources") command.Flags().StringSliceVar(&opts.SourceNamespaces, "source-namespaces", []string{}, "List of source namespaces for applications") + command.Flags().StringArrayVar(&opts.destinationServiceAccounts, "dest-service-accounts", []string{}, + "Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa)") } func getGroupKindList(values []string) []v1.GroupKind { @@ -98,8 +100,8 @@ func (opts *ProjectOpts) GetDestinationServiceAccounts() []v1alpha1.ApplicationD destinationServiceAccounts := make([]v1alpha1.ApplicationDestinationServiceAccount, 0) for _, destStr := range opts.destinationServiceAccounts { parts := strings.Split(destStr, ",") - if len(parts) != 2 { - log.Fatalf("Expected destination of the form: server,namespace. Received: %s", destStr) + if len(parts) != 3 { + log.Fatalf("Expected destination service account of the form: server,namespace, defaultServiceAccount. Received: %s", destStr) } else { destinationServiceAccounts = append(destinationServiceAccounts, v1alpha1.ApplicationDestinationServiceAccount{ Server: parts[0], diff --git a/cmd/util/project_test.go b/cmd/util/project_test.go index bde59d0ab5e88..8c61ee714f2c0 100644 --- a/cmd/util/project_test.go +++ b/cmd/util/project_test.go @@ -5,6 +5,8 @@ import ( "github.com/stretchr/testify/assert" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) func TestProjectOpts_ResourceLists(t *testing.T) { @@ -22,3 +24,27 @@ func TestProjectOpts_ResourceLists(t *testing.T) { []v1.GroupKind{{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"}}, opts.GetDeniedClusterResources(), ) } + +func TestProjectOpts_GetDestinationServiceAccounts(t *testing.T) { + opts := ProjectOpts{ + destinationServiceAccounts: []string{ + "https://192.168.99.100:8443,test-ns,test-sa", + "https://kubernetes.default.svc.local:6443,guestbook,guestbook-sa", + }, + } + + assert.ElementsMatch(t, + []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://192.168.99.100:8443", + Namespace: "test-ns", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.default.svc.local:6443", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-sa", + }, + }, opts.GetDestinationServiceAccounts(), + ) +} diff --git a/cmpserver/apiclient/plugin.pb.go b/cmpserver/apiclient/plugin.pb.go index b6fb8fca109b9..5e60bcfabe060 100644 --- a/cmpserver/apiclient/plugin.pb.go +++ b/cmpserver/apiclient/plugin.pb.go @@ -471,6 +471,7 @@ func (m *File) GetChunk() []byte { // CheckPluginConfigurationResponse contains a list of plugin configuration flags. type CheckPluginConfigurationResponse struct { IsDiscoveryConfigured bool `protobuf:"varint,1,opt,name=isDiscoveryConfigured,proto3" json:"isDiscoveryConfigured,omitempty"` + ProvideGitCreds bool `protobuf:"varint,2,opt,name=provideGitCreds,proto3" json:"provideGitCreds,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -516,6 +517,13 @@ func (m *CheckPluginConfigurationResponse) GetIsDiscoveryConfigured() bool { return false } +func (m *CheckPluginConfigurationResponse) GetProvideGitCreds() bool { + if m != nil { + return m.ProvideGitCreds + } + return false +} + func init() { proto.RegisterType((*AppStreamRequest)(nil), "plugin.AppStreamRequest") proto.RegisterType((*ManifestRequestMetadata)(nil), "plugin.ManifestRequestMetadata") @@ -530,48 +538,49 @@ func init() { func init() { proto.RegisterFile("cmpserver/plugin/plugin.proto", fileDescriptor_b21875a7079a06ed) } var fileDescriptor_b21875a7079a06ed = []byte{ - // 650 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xc1, 0x6e, 0xd3, 0x4c, - 0x10, 0x8e, 0x9b, 0xb4, 0x4d, 0x26, 0x95, 0xfe, 0x68, 0xf5, 0x53, 0x4c, 0x68, 0x43, 0xf0, 0x01, - 0xe5, 0x82, 0x23, 0x85, 0x5e, 0x91, 0x68, 0x4b, 0x68, 0x05, 0x0a, 0x8a, 0xb6, 0x1c, 0x80, 0x03, - 0xd2, 0xc6, 0x99, 0x24, 0x4b, 0xed, 0xdd, 0x65, 0xbd, 0x8e, 0x14, 0xb8, 0xf0, 0x36, 0xbc, 0x0a, - 0x47, 0x1e, 0x01, 0xf5, 0x35, 0xb8, 0x20, 0xaf, 0xed, 0x24, 0xa2, 0x69, 0x7b, 0xf2, 0xcc, 0x7c, - 0xb3, 0xdf, 0x7e, 0xb3, 0x33, 0x63, 0x38, 0x0c, 0x22, 0x15, 0xa3, 0x9e, 0xa3, 0xee, 0xaa, 0x30, - 0x99, 0x72, 0x91, 0x7f, 0x7c, 0xa5, 0xa5, 0x91, 0x64, 0x27, 0xf3, 0x9a, 0xfd, 0x29, 0x37, 0xb3, - 0x64, 0xe4, 0x07, 0x32, 0xea, 0x32, 0x3d, 0x95, 0x4a, 0xcb, 0xcf, 0xd6, 0x78, 0x1a, 0x8c, 0xbb, - 0xf3, 0x5e, 0x57, 0xa3, 0x92, 0x39, 0x8d, 0x35, 0xb9, 0x91, 0x7a, 0xb1, 0x66, 0x66, 0x74, 0xcd, - 0x87, 0x53, 0x29, 0xa7, 0x21, 0x76, 0xad, 0x37, 0x4a, 0x26, 0x5d, 0x8c, 0x94, 0xc9, 0x41, 0xef, - 0xbb, 0x03, 0x8d, 0x63, 0xa5, 0x2e, 0x8c, 0x46, 0x16, 0x51, 0xfc, 0x92, 0x60, 0x6c, 0xc8, 0x73, - 0xa8, 0x46, 0x68, 0xd8, 0x98, 0x19, 0xe6, 0x3a, 0x6d, 0xa7, 0x53, 0xef, 0x3d, 0xf2, 0x73, 0x85, - 0x03, 0x26, 0xf8, 0x04, 0x63, 0x93, 0xa7, 0x0e, 0xf2, 0xb4, 0xf3, 0x12, 0x5d, 0x1e, 0x21, 0x1e, - 0x54, 0x26, 0x3c, 0x44, 0x77, 0xcb, 0x1e, 0xdd, 0x2b, 0x8e, 0xbe, 0xe2, 0x21, 0x9e, 0x97, 0xa8, - 0xc5, 0x4e, 0x6a, 0xb0, 0xab, 0x33, 0x0a, 0xef, 0x87, 0x03, 0xf7, 0x6f, 0xa0, 0x25, 0x2e, 0xec, - 0x32, 0xa5, 0xde, 0xb2, 0x08, 0xad, 0x90, 0x1a, 0x2d, 0x5c, 0xd2, 0x02, 0x60, 0x4a, 0x51, 0x0c, - 0x87, 0xcc, 0xcc, 0xec, 0x55, 0x35, 0xba, 0x16, 0x21, 0x4d, 0xa8, 0x06, 0x33, 0x0c, 0x2e, 0xe3, - 0x24, 0x72, 0xcb, 0x16, 0x5d, 0xfa, 0x84, 0x40, 0x25, 0xe6, 0x5f, 0xd1, 0xad, 0xb4, 0x9d, 0x4e, - 0x99, 0x5a, 0x9b, 0x78, 0x50, 0x46, 0x31, 0x77, 0xb7, 0xdb, 0xe5, 0x4e, 0xbd, 0xd7, 0x28, 0x34, - 0xf7, 0xc5, 0xbc, 0x2f, 0x8c, 0x5e, 0xd0, 0x14, 0xf4, 0x8e, 0xa0, 0x5a, 0x04, 0x52, 0x0e, 0xb1, - 0x92, 0x65, 0x6d, 0xf2, 0x3f, 0x6c, 0xcf, 0x59, 0x98, 0x60, 0x2e, 0x27, 0x73, 0xbc, 0x21, 0x34, - 0x56, 0xe5, 0xc5, 0x4a, 0x8a, 0x18, 0xc9, 0x01, 0xd4, 0xa2, 0x3c, 0x16, 0xbb, 0x4e, 0xbb, 0xdc, - 0xa9, 0xd1, 0x55, 0x20, 0xad, 0x2d, 0x96, 0x89, 0x0e, 0xf0, 0xdd, 0x42, 0x15, 0x64, 0x6b, 0x11, - 0x6f, 0x02, 0x84, 0x2e, 0xbb, 0xbc, 0xe4, 0x6c, 0x43, 0x9d, 0xc7, 0x17, 0x89, 0x52, 0x52, 0x1b, - 0x1c, 0x5b, 0x61, 0x55, 0xba, 0x1e, 0x22, 0x3e, 0x10, 0x1e, 0xbf, 0xe4, 0x71, 0x20, 0xe7, 0xa8, - 0x17, 0x7d, 0xc1, 0x46, 0x21, 0x8e, 0x2d, 0x7f, 0x95, 0x6e, 0x40, 0xbc, 0x6f, 0xd0, 0x1a, 0x32, - 0xcd, 0x22, 0x34, 0xa8, 0xe3, 0x63, 0x21, 0x64, 0x22, 0x02, 0x8c, 0x50, 0xac, 0xea, 0xf8, 0x00, - 0xfb, 0xaa, 0xc8, 0x58, 0x4f, 0xc8, 0x8a, 0xaa, 0xf7, 0x1e, 0xfb, 0x6b, 0xe3, 0x38, 0xdc, 0x94, - 0x49, 0x6f, 0x20, 0xf0, 0x0e, 0xa0, 0x92, 0x4e, 0x4c, 0xfa, 0xa8, 0xc1, 0x2c, 0x11, 0x97, 0xb6, - 0xa0, 0x3d, 0x9a, 0x39, 0xde, 0x7b, 0x68, 0x9f, 0xa6, 0xed, 0x1c, 0xda, 0x3e, 0x9d, 0x4a, 0x31, - 0xe1, 0xd3, 0x44, 0x33, 0xc3, 0xa5, 0x58, 0x8a, 0x3b, 0x82, 0x7b, 0x6b, 0x45, 0x15, 0x39, 0xcb, - 0xa7, 0xd9, 0x0c, 0xf6, 0xfe, 0x6c, 0xc1, 0x61, 0xe6, 0x0e, 0x98, 0x60, 0x53, 0xab, 0x26, 0xbb, - 0xe5, 0x02, 0xf5, 0x9c, 0x07, 0x48, 0x5e, 0x43, 0xe3, 0x0c, 0x05, 0x6a, 0x66, 0xb0, 0x68, 0x2c, - 0x71, 0x8b, 0x89, 0xf9, 0x77, 0x99, 0x9a, 0xee, 0xf5, 0xd5, 0xc9, 0xf4, 0x79, 0xa5, 0x8e, 0x43, - 0x3e, 0x81, 0x7b, 0x53, 0x1d, 0x64, 0xdf, 0xcf, 0x36, 0xd7, 0x2f, 0x36, 0xd7, 0xef, 0xa7, 0x9b, - 0xdb, 0xec, 0x14, 0x8c, 0x77, 0xbd, 0x80, 0x57, 0x22, 0x6f, 0xe0, 0xbf, 0x01, 0x33, 0xc1, 0x6c, - 0x35, 0x2f, 0xb7, 0x48, 0x6d, 0x16, 0xc8, 0xf5, 0xe9, 0xb2, 0x62, 0x19, 0x3c, 0x38, 0x43, 0xb3, - 0x79, 0x24, 0x6e, 0xa1, 0x7d, 0x52, 0x20, 0xb7, 0x0f, 0x53, 0x7a, 0xc5, 0xc9, 0x8b, 0x9f, 0x57, - 0x2d, 0xe7, 0xd7, 0x55, 0xcb, 0xf9, 0x7d, 0xd5, 0x72, 0x3e, 0xf6, 0xee, 0xf8, 0x03, 0xae, 0xfe, - 0xa3, 0x4c, 0xf1, 0x20, 0xe4, 0x28, 0xcc, 0x68, 0xc7, 0xbe, 0xd6, 0xb3, 0xbf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xb5, 0x6b, 0xca, 0xa6, 0x65, 0x05, 0x00, 0x00, + // 670 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0x8e, 0x9b, 0xb4, 0x4d, 0x4e, 0x2a, 0x35, 0x1a, 0xdd, 0xdb, 0xeb, 0x9b, 0xdb, 0xe6, 0x06, + 0x2f, 0x50, 0x36, 0x38, 0x52, 0xe8, 0x16, 0x89, 0xb6, 0x84, 0x56, 0xa0, 0xa0, 0xc8, 0x65, 0x03, + 0x0b, 0xa4, 0x89, 0x73, 0x92, 0x0c, 0xb5, 0x67, 0x86, 0xf1, 0xd8, 0x52, 0x60, 0x83, 0x78, 0x19, + 0x5e, 0x85, 0x25, 0x8f, 0x80, 0xfa, 0x1a, 0x6c, 0x90, 0xc7, 0x76, 0x62, 0xb5, 0x69, 0xbb, 0xf2, + 0xf9, 0x9b, 0xcf, 0xdf, 0x39, 0xf3, 0x9d, 0x81, 0x23, 0x3f, 0x94, 0x11, 0xaa, 0x04, 0x55, 0x5f, + 0x06, 0xf1, 0x9c, 0xf1, 0xfc, 0xe3, 0x4a, 0x25, 0xb4, 0x20, 0x3b, 0x99, 0xd7, 0x1e, 0xce, 0x99, + 0x5e, 0xc4, 0x13, 0xd7, 0x17, 0x61, 0x9f, 0xaa, 0xb9, 0x90, 0x4a, 0x7c, 0x34, 0xc6, 0x13, 0x7f, + 0xda, 0x4f, 0x06, 0x7d, 0x85, 0x52, 0xe4, 0x30, 0xc6, 0x64, 0x5a, 0xa8, 0x65, 0xc9, 0xcc, 0xe0, + 0xda, 0xff, 0xcd, 0x85, 0x98, 0x07, 0xd8, 0x37, 0xde, 0x24, 0x9e, 0xf5, 0x31, 0x94, 0x3a, 0x4f, + 0x3a, 0x5f, 0x2d, 0x68, 0x9d, 0x48, 0x79, 0xa9, 0x15, 0xd2, 0xd0, 0xc3, 0x4f, 0x31, 0x46, 0x9a, + 0x3c, 0x83, 0x7a, 0x88, 0x9a, 0x4e, 0xa9, 0xa6, 0xb6, 0xd5, 0xb5, 0x7a, 0xcd, 0xc1, 0xff, 0x6e, + 0xce, 0x70, 0x44, 0x39, 0x9b, 0x61, 0xa4, 0xf3, 0xd2, 0x51, 0x5e, 0x76, 0x51, 0xf1, 0x56, 0x47, + 0x88, 0x03, 0xb5, 0x19, 0x0b, 0xd0, 0xde, 0x32, 0x47, 0xf7, 0x8a, 0xa3, 0x2f, 0x59, 0x80, 0x17, + 0x15, 0xcf, 0xe4, 0x4e, 0x1b, 0xb0, 0xab, 0x32, 0x08, 0xe7, 0xbb, 0x05, 0xff, 0xdc, 0x01, 0x4b, + 0x6c, 0xd8, 0xa5, 0x52, 0xbe, 0xa1, 0x21, 0x1a, 0x22, 0x0d, 0xaf, 0x70, 0x49, 0x07, 0x80, 0x4a, + 0xe9, 0x61, 0x30, 0xa6, 0x7a, 0x61, 0x7e, 0xd5, 0xf0, 0x4a, 0x11, 0xd2, 0x86, 0xba, 0xbf, 0x40, + 0xff, 0x2a, 0x8a, 0x43, 0xbb, 0x6a, 0xb2, 0x2b, 0x9f, 0x10, 0xa8, 0x45, 0xec, 0x33, 0xda, 0xb5, + 0xae, 0xd5, 0xab, 0x7a, 0xc6, 0x26, 0x0e, 0x54, 0x91, 0x27, 0xf6, 0x76, 0xb7, 0xda, 0x6b, 0x0e, + 0x5a, 0x05, 0xe7, 0x21, 0x4f, 0x86, 0x5c, 0xab, 0xa5, 0x97, 0x26, 0x9d, 0x63, 0xa8, 0x17, 0x81, + 0x14, 0x83, 0xaf, 0x69, 0x19, 0x9b, 0xfc, 0x05, 0xdb, 0x09, 0x0d, 0x62, 0xcc, 0xe9, 0x64, 0x8e, + 0x33, 0x86, 0xd6, 0xba, 0xbd, 0x48, 0x0a, 0x1e, 0x21, 0x39, 0x84, 0x46, 0x98, 0xc7, 0x22, 0xdb, + 0xea, 0x56, 0x7b, 0x0d, 0x6f, 0x1d, 0x48, 0x7b, 0x8b, 0x44, 0xac, 0x7c, 0x7c, 0xbb, 0x94, 0x05, + 0x58, 0x29, 0xe2, 0xcc, 0x80, 0x78, 0xab, 0x5b, 0x5e, 0x61, 0x76, 0xa1, 0xc9, 0xa2, 0xcb, 0x58, + 0x4a, 0xa1, 0x34, 0x4e, 0x0d, 0xb1, 0xba, 0x57, 0x0e, 0x11, 0x17, 0x08, 0x8b, 0x5e, 0xb0, 0xc8, + 0x17, 0x09, 0xaa, 0xe5, 0x90, 0xd3, 0x49, 0x80, 0x53, 0x83, 0x5f, 0xf7, 0x36, 0x64, 0x9c, 0x2f, + 0xd0, 0x19, 0x53, 0x45, 0x43, 0xd4, 0xa8, 0xa2, 0x13, 0xce, 0x45, 0xcc, 0x7d, 0x0c, 0x91, 0xaf, + 0xfb, 0x78, 0x07, 0x07, 0xb2, 0xa8, 0x28, 0x17, 0x64, 0x4d, 0x35, 0x07, 0x8f, 0xdc, 0x92, 0x1c, + 0xc7, 0x9b, 0x2a, 0xbd, 0x3b, 0x00, 0x9c, 0x43, 0xa8, 0xa5, 0x8a, 0x49, 0x87, 0xea, 0x2f, 0x62, + 0x7e, 0x65, 0x1a, 0xda, 0xf3, 0x32, 0xc7, 0xf9, 0x66, 0x41, 0xf7, 0x2c, 0xbd, 0xcf, 0xb1, 0xb9, + 0xa8, 0x33, 0xc1, 0x67, 0x6c, 0x1e, 0x2b, 0xaa, 0x99, 0xe0, 0x2b, 0x76, 0xc7, 0xf0, 0x77, 0xa9, + 0xab, 0xa2, 0x66, 0x35, 0x9b, 0xcd, 0x49, 0xd2, 0x83, 0x7d, 0xa9, 0x44, 0xc2, 0xa6, 0x78, 0xce, + 0xf4, 0x99, 0xc2, 0x69, 0x94, 0x8f, 0xe8, 0x66, 0x78, 0xf0, 0x7b, 0x0b, 0x8e, 0xb2, 0x83, 0x23, + 0xca, 0xe9, 0xdc, 0x10, 0xcf, 0xf8, 0x5c, 0xa2, 0x4a, 0x98, 0x8f, 0xe4, 0x15, 0xb4, 0xce, 0x91, + 0xa3, 0xa2, 0x1a, 0x0b, 0x0d, 0x10, 0xbb, 0x10, 0xd7, 0xcd, 0xbd, 0x6b, 0xdb, 0xb7, 0xb7, 0x2c, + 0xeb, 0xc4, 0xa9, 0xf4, 0x2c, 0xf2, 0x01, 0xec, 0xbb, 0x3a, 0x26, 0x07, 0x6e, 0xb6, 0xe4, 0x6e, + 0xb1, 0xe4, 0xee, 0x30, 0x5d, 0xf2, 0x76, 0xaf, 0x40, 0x7c, 0x68, 0x56, 0x4e, 0x85, 0xbc, 0x86, + 0xfd, 0x11, 0xd5, 0xfe, 0x62, 0x2d, 0xad, 0x7b, 0xa8, 0xb6, 0x8b, 0xcc, 0x6d, 0x21, 0x1a, 0xb2, + 0x14, 0xfe, 0x3d, 0x47, 0xbd, 0x59, 0x3d, 0xf7, 0xc0, 0x3e, 0x2e, 0x32, 0xf7, 0xeb, 0x2e, 0xfd, + 0xc5, 0xe9, 0xf3, 0x1f, 0xd7, 0x1d, 0xeb, 0xe7, 0x75, 0xc7, 0xfa, 0x75, 0xdd, 0xb1, 0xde, 0x0f, + 0x1e, 0x78, 0x2c, 0xd7, 0x4f, 0x2e, 0x95, 0xcc, 0x0f, 0x18, 0x72, 0x3d, 0xd9, 0x31, 0xd3, 0x7a, + 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xfa, 0x98, 0xfb, 0x90, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1252,6 +1261,16 @@ func (m *CheckPluginConfigurationResponse) MarshalToSizedBuffer(dAtA []byte) (in i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ProvideGitCreds { + i-- + if m.ProvideGitCreds { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } if m.IsDiscoveryConfigured { i-- if m.IsDiscoveryConfigured { @@ -1451,6 +1470,9 @@ func (m *CheckPluginConfigurationResponse) Size() (n int) { if m.IsDiscoveryConfigured { n += 2 } + if m.ProvideGitCreds { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2324,6 +2346,26 @@ func (m *CheckPluginConfigurationResponse) Unmarshal(dAtA []byte) error { } } m.IsDiscoveryConfigured = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProvideGitCreds", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlugin + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ProvideGitCreds = bool(v != 0) default: iNdEx = preIndex skippy, err := skipPlugin(dAtA[iNdEx:]) diff --git a/cmpserver/plugin/config.go b/cmpserver/plugin/config.go index faa718ff9fd2e..949e212d9cf76 100644 --- a/cmpserver/plugin/config.go +++ b/cmpserver/plugin/config.go @@ -28,6 +28,7 @@ type PluginConfigSpec struct { Discover Discover `json:"discover"` Parameters Parameters `yaml:"parameters"` PreserveFileMode bool `json:"preserveFileMode,omitempty"` + ProvideGitCreds bool `json:"provideGitCreds,omitempty"` } // Discover holds find and fileName diff --git a/cmpserver/plugin/plugin.go b/cmpserver/plugin/plugin.go index ee00f66ad9ecf..c708edf9a0e05 100644 --- a/cmpserver/plugin/plugin.go +++ b/cmpserver/plugin/plugin.go @@ -427,7 +427,7 @@ func getParametersAnnouncement(ctx context.Context, appDir string, announcements func (s *Service) CheckPluginConfiguration(ctx context.Context, _ *empty.Empty) (*apiclient.CheckPluginConfigurationResponse, error) { isDiscoveryConfigured := s.isDiscoveryConfigured() - response := &apiclient.CheckPluginConfigurationResponse{IsDiscoveryConfigured: isDiscoveryConfigured} + response := &apiclient.CheckPluginConfigurationResponse{IsDiscoveryConfigured: isDiscoveryConfigured, ProvideGitCreds: s.initConstants.PluginConfig.Spec.ProvideGitCreds} return response, nil } diff --git a/cmpserver/plugin/plugin.proto b/cmpserver/plugin/plugin.proto index 6f5b0d0cbf7b6..89fdd7418ceef 100644 --- a/cmpserver/plugin/plugin.proto +++ b/cmpserver/plugin/plugin.proto @@ -61,6 +61,7 @@ message File { // CheckPluginConfigurationResponse contains a list of plugin configuration flags. message CheckPluginConfigurationResponse { bool isDiscoveryConfigured = 1; + bool provideGitCreds = 2; } // ConfigManagementPlugin Service diff --git a/cmpserver/plugin/plugin_test.go b/cmpserver/plugin/plugin_test.go index 05001c31b3837..30bd0a97bedc5 100644 --- a/cmpserver/plugin/plugin_test.go +++ b/cmpserver/plugin/plugin_test.go @@ -451,8 +451,7 @@ func Test_getParametersAnnouncement_invalid_json(t *testing.T) { Args: []string{`[`}, } _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) - require.Error(t, err) - assert.Contains(t, err.Error(), "unexpected end of JSON input") + assert.ErrorContains(t, err, "unexpected end of JSON input") } func Test_getParametersAnnouncement_bad_command(t *testing.T) { @@ -461,8 +460,7 @@ func Test_getParametersAnnouncement_bad_command(t *testing.T) { Args: []string{"1"}, } _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) - require.Error(t, err) - assert.Contains(t, err.Error(), "error executing dynamic parameter output command") + assert.ErrorContains(t, err, "error executing dynamic parameter output command") } func Test_getTempDirMustCleanup(t *testing.T) { diff --git a/commitserver/apiclient/clientset.go b/commitserver/apiclient/clientset.go new file mode 100644 index 0000000000000..795766e54e3db --- /dev/null +++ b/commitserver/apiclient/clientset.go @@ -0,0 +1,49 @@ +package apiclient + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "github.com/argoproj/argo-cd/v2/util/io" +) + +// Clientset represents commit server api clients +type Clientset interface { + NewCommitServerClient() (io.Closer, CommitServiceClient, error) +} + +type clientSet struct { + address string +} + +// NewCommitServerClient creates new instance of commit server client +func (c *clientSet) NewCommitServerClient() (io.Closer, CommitServiceClient, error) { + conn, err := NewConnection(c.address) + if err != nil { + return nil, nil, fmt.Errorf("failed to open a new connection to commit server: %w", err) + } + return conn, NewCommitServiceClient(conn), nil +} + +// NewConnection creates new connection to commit server +func NewConnection(address string) (*grpc.ClientConn, error) { + var opts []grpc.DialOption + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + + // TODO: switch to grpc.NewClient. + // nolint:staticcheck + conn, err := grpc.Dial(address, opts...) + if err != nil { + log.Errorf("Unable to connect to commit service with address %s", address) + return nil, err + } + return conn, nil +} + +// NewCommitServerClientset creates new instance of commit server Clientset +func NewCommitServerClientset(address string) Clientset { + return &clientSet{address: address} +} diff --git a/commitserver/apiclient/commit.pb.go b/commitserver/apiclient/commit.pb.go new file mode 100644 index 0000000000000..3e371575827ac --- /dev/null +++ b/commitserver/apiclient/commit.pb.go @@ -0,0 +1,1382 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: commitserver/commit/commit.proto + +package apiclient + +import ( + context "context" + fmt "fmt" + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + 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 + +// CommitHydratedManifestsRequest is the request to commit hydrated manifests to a repository. +type CommitHydratedManifestsRequest struct { + // Repo contains repository information including, at minimum, the URL of the repository. Generally it will contain + // repo credentials. + Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` + // SyncBranch is the branch Argo CD syncs from, i.e. the hydrated branch. + SyncBranch string `protobuf:"bytes,2,opt,name=syncBranch,proto3" json:"syncBranch,omitempty"` + // TargetBranch is the branch Argo CD is committing to, i.e. the branch that will be updated. + TargetBranch string `protobuf:"bytes,3,opt,name=targetBranch,proto3" json:"targetBranch,omitempty"` + // DrySha is the commit SHA from the dry branch, i.e. pre-rendered manifest branch. + DrySha string `protobuf:"bytes,4,opt,name=drySha,proto3" json:"drySha,omitempty"` + // CommitMessage is the commit message to use when committing changes. + CommitMessage string `protobuf:"bytes,5,opt,name=commitMessage,proto3" json:"commitMessage,omitempty"` + // Paths contains the paths to write hydrated manifests to, along with the manifests and commands to execute. + Paths []*PathDetails `protobuf:"bytes,6,rep,name=paths,proto3" json:"paths,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CommitHydratedManifestsRequest) Reset() { *m = CommitHydratedManifestsRequest{} } +func (m *CommitHydratedManifestsRequest) String() string { return proto.CompactTextString(m) } +func (*CommitHydratedManifestsRequest) ProtoMessage() {} +func (*CommitHydratedManifestsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cf3a3abbc35e3069, []int{0} +} +func (m *CommitHydratedManifestsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommitHydratedManifestsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommitHydratedManifestsRequest.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 *CommitHydratedManifestsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitHydratedManifestsRequest.Merge(m, src) +} +func (m *CommitHydratedManifestsRequest) XXX_Size() int { + return m.Size() +} +func (m *CommitHydratedManifestsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CommitHydratedManifestsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CommitHydratedManifestsRequest proto.InternalMessageInfo + +func (m *CommitHydratedManifestsRequest) GetRepo() *v1alpha1.Repository { + if m != nil { + return m.Repo + } + return nil +} + +func (m *CommitHydratedManifestsRequest) GetSyncBranch() string { + if m != nil { + return m.SyncBranch + } + return "" +} + +func (m *CommitHydratedManifestsRequest) GetTargetBranch() string { + if m != nil { + return m.TargetBranch + } + return "" +} + +func (m *CommitHydratedManifestsRequest) GetDrySha() string { + if m != nil { + return m.DrySha + } + return "" +} + +func (m *CommitHydratedManifestsRequest) GetCommitMessage() string { + if m != nil { + return m.CommitMessage + } + return "" +} + +func (m *CommitHydratedManifestsRequest) GetPaths() []*PathDetails { + if m != nil { + return m.Paths + } + return nil +} + +// PathDetails holds information about hydrated manifests to be written to a particular path in the hydrated manifests +// commit. +type PathDetails struct { + // Path is the path to write the hydrated manifests to. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // Manifests contains the manifests to write to the path. + Manifests []*HydratedManifestDetails `protobuf:"bytes,2,rep,name=manifests,proto3" json:"manifests,omitempty"` + // Commands contains the commands executed when hydrating the manifests. + Commands []string `protobuf:"bytes,3,rep,name=commands,proto3" json:"commands,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PathDetails) Reset() { *m = PathDetails{} } +func (m *PathDetails) String() string { return proto.CompactTextString(m) } +func (*PathDetails) ProtoMessage() {} +func (*PathDetails) Descriptor() ([]byte, []int) { + return fileDescriptor_cf3a3abbc35e3069, []int{1} +} +func (m *PathDetails) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PathDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PathDetails.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 *PathDetails) XXX_Merge(src proto.Message) { + xxx_messageInfo_PathDetails.Merge(m, src) +} +func (m *PathDetails) XXX_Size() int { + return m.Size() +} +func (m *PathDetails) XXX_DiscardUnknown() { + xxx_messageInfo_PathDetails.DiscardUnknown(m) +} + +var xxx_messageInfo_PathDetails proto.InternalMessageInfo + +func (m *PathDetails) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *PathDetails) GetManifests() []*HydratedManifestDetails { + if m != nil { + return m.Manifests + } + return nil +} + +func (m *PathDetails) GetCommands() []string { + if m != nil { + return m.Commands + } + return nil +} + +// ManifestDetails contains the hydrated manifests. +type HydratedManifestDetails struct { + // ManifestJSON is the hydrated manifest as JSON. + ManifestJSON string `protobuf:"bytes,1,opt,name=manifestJSON,proto3" json:"manifestJSON,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HydratedManifestDetails) Reset() { *m = HydratedManifestDetails{} } +func (m *HydratedManifestDetails) String() string { return proto.CompactTextString(m) } +func (*HydratedManifestDetails) ProtoMessage() {} +func (*HydratedManifestDetails) Descriptor() ([]byte, []int) { + return fileDescriptor_cf3a3abbc35e3069, []int{2} +} +func (m *HydratedManifestDetails) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HydratedManifestDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HydratedManifestDetails.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 *HydratedManifestDetails) XXX_Merge(src proto.Message) { + xxx_messageInfo_HydratedManifestDetails.Merge(m, src) +} +func (m *HydratedManifestDetails) XXX_Size() int { + return m.Size() +} +func (m *HydratedManifestDetails) XXX_DiscardUnknown() { + xxx_messageInfo_HydratedManifestDetails.DiscardUnknown(m) +} + +var xxx_messageInfo_HydratedManifestDetails proto.InternalMessageInfo + +func (m *HydratedManifestDetails) GetManifestJSON() string { + if m != nil { + return m.ManifestJSON + } + return "" +} + +// ManifestsResponse is the response to the ManifestsRequest. +type CommitHydratedManifestsResponse struct { + // HydratedSha is the commit SHA of the hydrated manifests commit. + HydratedSha string `protobuf:"bytes,1,opt,name=hydratedSha,proto3" json:"hydratedSha,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CommitHydratedManifestsResponse) Reset() { *m = CommitHydratedManifestsResponse{} } +func (m *CommitHydratedManifestsResponse) String() string { return proto.CompactTextString(m) } +func (*CommitHydratedManifestsResponse) ProtoMessage() {} +func (*CommitHydratedManifestsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cf3a3abbc35e3069, []int{3} +} +func (m *CommitHydratedManifestsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommitHydratedManifestsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommitHydratedManifestsResponse.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 *CommitHydratedManifestsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitHydratedManifestsResponse.Merge(m, src) +} +func (m *CommitHydratedManifestsResponse) XXX_Size() int { + return m.Size() +} +func (m *CommitHydratedManifestsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CommitHydratedManifestsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CommitHydratedManifestsResponse proto.InternalMessageInfo + +func (m *CommitHydratedManifestsResponse) GetHydratedSha() string { + if m != nil { + return m.HydratedSha + } + return "" +} + +func init() { + proto.RegisterType((*CommitHydratedManifestsRequest)(nil), "CommitHydratedManifestsRequest") + proto.RegisterType((*PathDetails)(nil), "PathDetails") + proto.RegisterType((*HydratedManifestDetails)(nil), "HydratedManifestDetails") + proto.RegisterType((*CommitHydratedManifestsResponse)(nil), "CommitHydratedManifestsResponse") +} + +func init() { proto.RegisterFile("commitserver/commit/commit.proto", fileDescriptor_cf3a3abbc35e3069) } + +var fileDescriptor_cf3a3abbc35e3069 = []byte{ + // 446 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0x86, 0xe5, 0x24, 0x8d, 0xc8, 0xa4, 0xbd, 0xec, 0x81, 0x5a, 0x39, 0xb8, 0x96, 0xc5, 0x21, + 0x17, 0xd6, 0xaa, 0x11, 0xdc, 0xb8, 0x34, 0x1c, 0x2a, 0x44, 0x01, 0x39, 0x37, 0x54, 0x09, 0x6d, + 0xd7, 0x83, 0xbd, 0x34, 0xf6, 0x2e, 0xbb, 0x1b, 0x4b, 0x79, 0x1f, 0x1e, 0x86, 0x23, 0x8f, 0x80, + 0xf2, 0x24, 0xc8, 0x6b, 0x9b, 0xc6, 0x48, 0x69, 0x4f, 0x9e, 0xf9, 0x67, 0xf4, 0xcd, 0xe8, 0xf7, + 0x2c, 0x84, 0x5c, 0x96, 0xa5, 0xb0, 0x06, 0x75, 0x8d, 0x3a, 0x6e, 0x93, 0xee, 0x43, 0x95, 0x96, + 0x56, 0x2e, 0x3e, 0xe4, 0xc2, 0x16, 0xdb, 0x3b, 0xca, 0x65, 0x19, 0x33, 0x9d, 0x4b, 0xa5, 0xe5, + 0x77, 0x17, 0xbc, 0xe4, 0x59, 0x5c, 0x27, 0xb1, 0xba, 0xcf, 0x63, 0xa6, 0x84, 0x89, 0x99, 0x52, + 0x1b, 0xc1, 0x99, 0x15, 0xb2, 0x8a, 0xeb, 0x4b, 0xb6, 0x51, 0x05, 0xbb, 0x8c, 0x73, 0xac, 0x50, + 0x33, 0x8b, 0x59, 0x4b, 0x8b, 0x7e, 0x8e, 0x20, 0x58, 0x39, 0xfc, 0xf5, 0x2e, 0x73, 0x85, 0x1b, + 0x56, 0x89, 0x6f, 0x68, 0xac, 0x49, 0xf1, 0xc7, 0x16, 0x8d, 0x25, 0xb7, 0x30, 0xd1, 0xa8, 0xa4, + 0xef, 0x85, 0xde, 0x72, 0x9e, 0x5c, 0xd3, 0x87, 0xf9, 0xb4, 0x9f, 0xef, 0x82, 0xaf, 0x3c, 0xa3, + 0x75, 0x42, 0xd5, 0x7d, 0x4e, 0x9b, 0xf9, 0xf4, 0x60, 0x3e, 0xed, 0xe7, 0xd3, 0x14, 0x95, 0x34, + 0xc2, 0x4a, 0xbd, 0x4b, 0x1d, 0x95, 0x04, 0x00, 0x66, 0x57, 0xf1, 0x2b, 0xcd, 0x2a, 0x5e, 0xf8, + 0xa3, 0xd0, 0x5b, 0xce, 0xd2, 0x03, 0x85, 0x44, 0x70, 0x6a, 0x99, 0xce, 0xd1, 0x76, 0x1d, 0x63, + 0xd7, 0x31, 0xd0, 0xc8, 0x73, 0x98, 0x66, 0x7a, 0xb7, 0x2e, 0x98, 0x3f, 0x71, 0xd5, 0x2e, 0x23, + 0x2f, 0xe0, 0xac, 0xb5, 0xee, 0x06, 0x8d, 0x61, 0x39, 0xfa, 0x27, 0xae, 0x3c, 0x14, 0x49, 0x04, + 0x27, 0x8a, 0xd9, 0xc2, 0xf8, 0xd3, 0x70, 0xbc, 0x9c, 0x27, 0xa7, 0xf4, 0x33, 0xb3, 0xc5, 0x3b, + 0xb4, 0x4c, 0x6c, 0x4c, 0xda, 0x96, 0xa2, 0x2d, 0xcc, 0x0f, 0x54, 0x42, 0x60, 0xd2, 0xe8, 0xce, + 0x92, 0x59, 0xea, 0x62, 0xf2, 0x06, 0x66, 0x65, 0x6f, 0x9d, 0x3f, 0x72, 0x28, 0x9f, 0xfe, 0x6f, + 0x6a, 0x8f, 0x7d, 0x68, 0x25, 0x0b, 0x78, 0xd6, 0xec, 0xc3, 0xaa, 0xcc, 0xf8, 0xe3, 0x70, 0xbc, + 0x9c, 0xa5, 0xff, 0xf2, 0xe8, 0x2d, 0x9c, 0x1f, 0x21, 0x34, 0xbe, 0xf4, 0x8c, 0xf7, 0xeb, 0x4f, + 0x1f, 0xbb, 0x55, 0x06, 0x5a, 0xb4, 0x82, 0x8b, 0xa3, 0xff, 0xd6, 0x28, 0x59, 0x19, 0x24, 0x21, + 0xcc, 0x8b, 0xae, 0xd8, 0xf8, 0xd7, 0x52, 0x0e, 0xa5, 0xa4, 0x84, 0xb3, 0x16, 0xb2, 0x46, 0x5d, + 0x0b, 0x8e, 0xe4, 0x16, 0xce, 0x8f, 0x50, 0xc9, 0x05, 0x7d, 0xfc, 0x96, 0x16, 0x21, 0x7d, 0x62, + 0xa1, 0xab, 0xd5, 0xaf, 0x7d, 0xe0, 0xfd, 0xde, 0x07, 0xde, 0x9f, 0x7d, 0xe0, 0x7d, 0x79, 0xfd, + 0xc4, 0xb1, 0x0f, 0x5e, 0x0b, 0x53, 0x82, 0x6f, 0x04, 0x56, 0xf6, 0x6e, 0xea, 0x8e, 0xfb, 0xd5, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0xb8, 0xdf, 0x48, 0x4e, 0x03, 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 + +// CommitServiceClient is the client API for CommitService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type CommitServiceClient interface { + // Commit commits hydrated manifests to a repository. + CommitHydratedManifests(ctx context.Context, in *CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*CommitHydratedManifestsResponse, error) +} + +type commitServiceClient struct { + cc *grpc.ClientConn +} + +func NewCommitServiceClient(cc *grpc.ClientConn) CommitServiceClient { + return &commitServiceClient{cc} +} + +func (c *commitServiceClient) CommitHydratedManifests(ctx context.Context, in *CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*CommitHydratedManifestsResponse, error) { + out := new(CommitHydratedManifestsResponse) + err := c.cc.Invoke(ctx, "/CommitService/CommitHydratedManifests", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CommitServiceServer is the server API for CommitService service. +type CommitServiceServer interface { + // Commit commits hydrated manifests to a repository. + CommitHydratedManifests(context.Context, *CommitHydratedManifestsRequest) (*CommitHydratedManifestsResponse, error) +} + +// UnimplementedCommitServiceServer can be embedded to have forward compatible implementations. +type UnimplementedCommitServiceServer struct { +} + +func (*UnimplementedCommitServiceServer) CommitHydratedManifests(ctx context.Context, req *CommitHydratedManifestsRequest) (*CommitHydratedManifestsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CommitHydratedManifests not implemented") +} + +func RegisterCommitServiceServer(s *grpc.Server, srv CommitServiceServer) { + s.RegisterService(&_CommitService_serviceDesc, srv) +} + +func _CommitService_CommitHydratedManifests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CommitHydratedManifestsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CommitServiceServer).CommitHydratedManifests(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/CommitService/CommitHydratedManifests", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CommitServiceServer).CommitHydratedManifests(ctx, req.(*CommitHydratedManifestsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _CommitService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "CommitService", + HandlerType: (*CommitServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CommitHydratedManifests", + Handler: _CommitService_CommitHydratedManifests_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "commitserver/commit/commit.proto", +} + +func (m *CommitHydratedManifestsRequest) 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 *CommitHydratedManifestsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommitHydratedManifestsRequest) 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.Paths) > 0 { + for iNdEx := len(m.Paths) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Paths[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.CommitMessage) > 0 { + i -= len(m.CommitMessage) + copy(dAtA[i:], m.CommitMessage) + i = encodeVarintCommit(dAtA, i, uint64(len(m.CommitMessage))) + i-- + dAtA[i] = 0x2a + } + if len(m.DrySha) > 0 { + i -= len(m.DrySha) + copy(dAtA[i:], m.DrySha) + i = encodeVarintCommit(dAtA, i, uint64(len(m.DrySha))) + i-- + dAtA[i] = 0x22 + } + if len(m.TargetBranch) > 0 { + i -= len(m.TargetBranch) + copy(dAtA[i:], m.TargetBranch) + i = encodeVarintCommit(dAtA, i, uint64(len(m.TargetBranch))) + i-- + dAtA[i] = 0x1a + } + if len(m.SyncBranch) > 0 { + i -= len(m.SyncBranch) + copy(dAtA[i:], m.SyncBranch) + i = encodeVarintCommit(dAtA, i, uint64(len(m.SyncBranch))) + i-- + dAtA[i] = 0x12 + } + if m.Repo != nil { + { + size, err := m.Repo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PathDetails) 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 *PathDetails) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PathDetails) 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.Commands) > 0 { + for iNdEx := len(m.Commands) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Commands[iNdEx]) + copy(dAtA[i:], m.Commands[iNdEx]) + i = encodeVarintCommit(dAtA, i, uint64(len(m.Commands[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Manifests) > 0 { + for iNdEx := len(m.Manifests) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Manifests[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintCommit(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *HydratedManifestDetails) 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 *HydratedManifestDetails) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HydratedManifestDetails) 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.ManifestJSON) > 0 { + i -= len(m.ManifestJSON) + copy(dAtA[i:], m.ManifestJSON) + i = encodeVarintCommit(dAtA, i, uint64(len(m.ManifestJSON))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CommitHydratedManifestsResponse) 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 *CommitHydratedManifestsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommitHydratedManifestsResponse) 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.HydratedSha) > 0 { + i -= len(m.HydratedSha) + copy(dAtA[i:], m.HydratedSha) + i = encodeVarintCommit(dAtA, i, uint64(len(m.HydratedSha))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintCommit(dAtA []byte, offset int, v uint64) int { + offset -= sovCommit(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *CommitHydratedManifestsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Repo != nil { + l = m.Repo.Size() + n += 1 + l + sovCommit(uint64(l)) + } + l = len(m.SyncBranch) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + l = len(m.TargetBranch) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + l = len(m.DrySha) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + l = len(m.CommitMessage) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + if len(m.Paths) > 0 { + for _, e := range m.Paths { + l = e.Size() + n += 1 + l + sovCommit(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PathDetails) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Path) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + if len(m.Manifests) > 0 { + for _, e := range m.Manifests { + l = e.Size() + n += 1 + l + sovCommit(uint64(l)) + } + } + if len(m.Commands) > 0 { + for _, s := range m.Commands { + l = len(s) + n += 1 + l + sovCommit(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *HydratedManifestDetails) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ManifestJSON) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CommitHydratedManifestsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.HydratedSha) + if l > 0 { + n += 1 + l + sovCommit(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovCommit(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCommit(x uint64) (n int) { + return sovCommit(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *CommitHydratedManifestsRequest) 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 ErrIntOverflowCommit + } + 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: CommitHydratedManifestsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommitHydratedManifestsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Repo == nil { + m.Repo = &v1alpha1.Repository{} + } + if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncBranch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SyncBranch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetBranch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetBranch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DrySha", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DrySha = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitMessage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CommitMessage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Paths = append(m.Paths, &PathDetails{}) + if err := m.Paths[len(m.Paths)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommit + } + 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 *PathDetails) 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 ErrIntOverflowCommit + } + 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: PathDetails: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PathDetails: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Manifests", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Manifests = append(m.Manifests, &HydratedManifestDetails{}) + if err := m.Manifests[len(m.Manifests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commands", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Commands = append(m.Commands, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommit + } + 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 *HydratedManifestDetails) 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 ErrIntOverflowCommit + } + 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: HydratedManifestDetails: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HydratedManifestDetails: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ManifestJSON", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ManifestJSON = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommit + } + 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 *CommitHydratedManifestsResponse) 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 ErrIntOverflowCommit + } + 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: CommitHydratedManifestsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommitHydratedManifestsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HydratedSha", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommit + } + 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 ErrInvalidLengthCommit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HydratedSha = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommit + } + 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 skipCommit(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, ErrIntOverflowCommit + } + 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, ErrIntOverflowCommit + } + 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, ErrIntOverflowCommit + } + 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, ErrInvalidLengthCommit + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCommit + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthCommit + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthCommit = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCommit = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCommit = fmt.Errorf("proto: unexpected end of group") +) diff --git a/commitserver/apiclient/mocks/Clientset.go b/commitserver/apiclient/mocks/Clientset.go new file mode 100644 index 0000000000000..bb51a52c9a623 --- /dev/null +++ b/commitserver/apiclient/mocks/Clientset.go @@ -0,0 +1,68 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + io "github.com/argoproj/argo-cd/v2/util/io" + + mock "github.com/stretchr/testify/mock" +) + +// Clientset is an autogenerated mock type for the Clientset type +type Clientset struct { + mock.Mock +} + +// NewCommitServerClient provides a mock function with given fields: +func (_m *Clientset) NewCommitServerClient() (io.Closer, apiclient.CommitServiceClient, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for NewCommitServerClient") + } + + var r0 io.Closer + var r1 apiclient.CommitServiceClient + var r2 error + if rf, ok := ret.Get(0).(func() (io.Closer, apiclient.CommitServiceClient, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() io.Closer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.Closer) + } + } + + if rf, ok := ret.Get(1).(func() apiclient.CommitServiceClient); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(apiclient.CommitServiceClient) + } + } + + if rf, ok := ret.Get(2).(func() error); ok { + r2 = rf() + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// NewClientset creates a new instance of Clientset. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClientset(t interface { + mock.TestingT + Cleanup(func()) +}) *Clientset { + mock := &Clientset{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/commitserver/apiclient/mocks/CommitServiceClient.go b/commitserver/apiclient/mocks/CommitServiceClient.go new file mode 100644 index 0000000000000..d122aa1a710c1 --- /dev/null +++ b/commitserver/apiclient/mocks/CommitServiceClient.go @@ -0,0 +1,69 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + apiclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + + grpc "google.golang.org/grpc" + + mock "github.com/stretchr/testify/mock" +) + +// CommitServiceClient is an autogenerated mock type for the CommitServiceClient type +type CommitServiceClient struct { + mock.Mock +} + +// CommitHydratedManifests provides a mock function with given fields: ctx, in, opts +func (_m *CommitServiceClient) CommitHydratedManifests(ctx context.Context, in *apiclient.CommitHydratedManifestsRequest, opts ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error) { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, in) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CommitHydratedManifests") + } + + var r0 *apiclient.CommitHydratedManifestsResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) (*apiclient.CommitHydratedManifestsResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) *apiclient.CommitHydratedManifestsResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*apiclient.CommitHydratedManifestsResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *apiclient.CommitHydratedManifestsRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewCommitServiceClient creates a new instance of CommitServiceClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewCommitServiceClient(t interface { + mock.TestingT + Cleanup(func()) +}) *CommitServiceClient { + mock := &CommitServiceClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/commitserver/commit/commit.go b/commitserver/commit/commit.go new file mode 100644 index 0000000000000..0a40b3a7d6042 --- /dev/null +++ b/commitserver/commit/commit.go @@ -0,0 +1,225 @@ +package commit + +import ( + "context" + "fmt" + "os" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/io/files" +) + +// Service is the service that handles commit requests. +type Service struct { + gitCredsStore git.CredsStore + metricsServer *metrics.Server + repoClientFactory RepoClientFactory +} + +// NewService returns a new instance of the commit service. +func NewService(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *Service { + return &Service{ + gitCredsStore: gitCredsStore, + metricsServer: metricsServer, + repoClientFactory: NewRepoClientFactory(gitCredsStore, metricsServer), + } +} + +// CommitHydratedManifests handles a commit request. It clones the repository, checks out the sync branch, checks out +// the target branch, clears the repository contents, writes the manifests to the repository, commits the changes, and +// pushes the changes. It returns the hydrated revision SHA and an error if one occurred. +func (s *Service) CommitHydratedManifests(ctx context.Context, r *apiclient.CommitHydratedManifestsRequest) (*apiclient.CommitHydratedManifestsResponse, error) { + // This method is intentionally short. It's a wrapper around handleCommitRequest that adds metrics and logging. + // Keep logic here minimal and put most of the logic in handleCommitRequest. + startTime := time.Now() + + // We validate for a nil repo in handleCommitRequest, but we need to check for a nil repo here to get the repo URL + // for metrics. + var repoURL string + if r.Repo != nil { + repoURL = r.Repo.Repo + } + + var err error + s.metricsServer.IncPendingCommitRequest(repoURL) + defer func() { + s.metricsServer.DecPendingCommitRequest(repoURL) + commitResponseType := metrics.CommitResponseTypeSuccess + if err != nil { + commitResponseType = metrics.CommitResponseTypeFailure + } + s.metricsServer.IncCommitRequest(repoURL, commitResponseType) + s.metricsServer.ObserveCommitRequestDuration(repoURL, commitResponseType, time.Since(startTime)) + }() + + logCtx := log.WithFields(log.Fields{"branch": r.TargetBranch, "drySHA": r.DrySha}) + + out, sha, err := s.handleCommitRequest(logCtx, r) + if err != nil { + logCtx.WithError(err).WithField("output", out).Error("failed to handle commit request") + + // No need to wrap this error, sufficient context is build in handleCommitRequest. + return &apiclient.CommitHydratedManifestsResponse{}, err + } + + logCtx.Info("Successfully handled commit request") + return &apiclient.CommitHydratedManifestsResponse{ + HydratedSha: sha, + }, nil +} + +// handleCommitRequest handles the commit request. It clones the repository, checks out the sync branch, checks out the +// target branch, clears the repository contents, writes the manifests to the repository, commits the changes, and pushes +// the changes. It returns the output of the git commands and an error if one occurred. +func (s *Service) handleCommitRequest(logCtx *log.Entry, r *apiclient.CommitHydratedManifestsRequest) (string, string, error) { + if r.Repo == nil { + return "", "", fmt.Errorf("repo is required") + } + if r.Repo.Repo == "" { + return "", "", fmt.Errorf("repo URL is required") + } + if r.TargetBranch == "" { + return "", "", fmt.Errorf("target branch is required") + } + if r.SyncBranch == "" { + return "", "", fmt.Errorf("sync branch is required") + } + + logCtx = logCtx.WithField("repo", r.Repo.Repo) + logCtx.Debug("Initiating git client") + gitClient, dirPath, cleanup, err := s.initGitClient(logCtx, r) + if err != nil { + return "", "", fmt.Errorf("failed to init git client: %w", err) + } + defer cleanup() + + logCtx.Debugf("Checking out sync branch %s", r.SyncBranch) + var out string + out, err = gitClient.CheckoutOrOrphan(r.SyncBranch, false) + if err != nil { + return out, "", fmt.Errorf("failed to checkout sync branch: %w", err) + } + + logCtx.Debugf("Checking out target branch %s", r.TargetBranch) + out, err = gitClient.CheckoutOrNew(r.TargetBranch, r.SyncBranch, false) + if err != nil { + return out, "", fmt.Errorf("failed to checkout target branch: %w", err) + } + + logCtx.Debug("Clearing repo contents") + out, err = gitClient.RemoveContents() + if err != nil { + return out, "", fmt.Errorf("failed to clear repo: %w", err) + } + + logCtx.Debug("Writing manifests") + err = WriteForPaths(dirPath, r.Repo.Repo, r.DrySha, r.Paths) + if err != nil { + return "", "", fmt.Errorf("failed to write manifests: %w", err) + } + + logCtx.Debug("Committing and pushing changes") + out, err = gitClient.CommitAndPush(r.TargetBranch, r.CommitMessage) + if err != nil { + return out, "", fmt.Errorf("failed to commit and push: %w", err) + } + + logCtx.Debug("Getting commit SHA") + sha, err := gitClient.CommitSHA() + if err != nil { + return "", "", fmt.Errorf("failed to get commit SHA: %w", err) + } + + return "", sha, nil +} + +// initGitClient initializes a git client for the given repository and returns the client, the path to the directory where +// the repository is cloned, a cleanup function that should be called when the directory is no longer needed, and an error +// if one occurred. +func (s *Service) initGitClient(logCtx *log.Entry, r *apiclient.CommitHydratedManifestsRequest) (git.Client, string, func(), error) { + dirPath, err := files.CreateTempDir("/tmp/_commit-service") + if err != nil { + return nil, "", nil, fmt.Errorf("failed to create temp dir: %w", err) + } + // Call cleanupOrLog in this function if an error occurs to ensure the temp dir is cleaned up. + cleanupOrLog := func() { + err := os.RemoveAll(dirPath) + if err != nil { + logCtx.WithError(err).Error("failed to cleanup temp dir") + } + } + + gitClient, err := s.repoClientFactory.NewClient(r.Repo, dirPath) + if err != nil { + cleanupOrLog() + return nil, "", nil, fmt.Errorf("failed to create git client: %w", err) + } + + logCtx.Debugf("Initializing repo %s", r.Repo.Repo) + err = gitClient.Init() + if err != nil { + cleanupOrLog() + return nil, "", nil, fmt.Errorf("failed to init git client: %w", err) + } + + logCtx.Debugf("Fetching repo %s", r.Repo.Repo) + err = gitClient.Fetch("") + if err != nil { + cleanupOrLog() + return nil, "", nil, fmt.Errorf("failed to clone repo: %w", err) + } + + // FIXME: make it work for GHE + //logCtx.Debugf("Getting user info for repo credentials") + //gitCreds := r.Repo.GetGitCreds(s.gitCredsStore) + //startTime := time.Now() + //authorName, authorEmail, err := gitCreds.GetUserInfo(ctx) + //s.metricsServer.ObserveUserInfoRequestDuration(r.Repo.Repo, getCredentialType(r.Repo), time.Since(startTime)) + //if err != nil { + // cleanupOrLog() + // return nil, "", nil, fmt.Errorf("failed to get github app info: %w", err) + //} + var authorName, authorEmail string + + if authorName == "" { + authorName = "Argo CD" + } + if authorEmail == "" { + logCtx.Warnf("Author email not available, using 'argo-cd@example.com'.") + authorEmail = "argo-cd@example.com" + } + + logCtx.Debugf("Setting author %s <%s>", authorName, authorEmail) + _, err = gitClient.SetAuthor(authorName, authorEmail) + if err != nil { + cleanupOrLog() + return nil, "", nil, fmt.Errorf("failed to set author: %w", err) + } + + return gitClient, dirPath, cleanupOrLog, nil +} + +type hydratorMetadataFile struct { + RepoURL string `json:"repoURL"` + DrySHA string `json:"drySha"` + Commands []string `json:"commands"` +} + +// TODO: make this configurable via ConfigMap. +var manifestHydrationReadmeTemplate = ` +# Manifest Hydration + +To hydrate the manifests in this repository, run the following commands: + +` + "```shell\n" + ` +git clone {{ .RepoURL }} +# cd into the cloned directory +git checkout {{ .DrySHA }} +{{ range $command := .Commands -}} +{{ $command }} +{{ end -}}` + "```" diff --git a/commitserver/commit/commit.proto b/commitserver/commit/commit.proto new file mode 100644 index 0000000000000..fdf8b23c0d00e --- /dev/null +++ b/commitserver/commit/commit.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +option go_package = "github.com/argoproj/argo-cd/v2/commitserver/apiclient"; + +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.proto"; + +// CommitHydratedManifestsRequest is the request to commit hydrated manifests to a repository. +message CommitHydratedManifestsRequest { + // Repo contains repository information including, at minimum, the URL of the repository. Generally it will contain + // repo credentials. + github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; + // SyncBranch is the branch Argo CD syncs from, i.e. the hydrated branch. + string syncBranch = 2; + // TargetBranch is the branch Argo CD is committing to, i.e. the branch that will be updated. + string targetBranch = 3; + // DrySha is the commit SHA from the dry branch, i.e. pre-rendered manifest branch. + string drySha = 4; + // CommitMessage is the commit message to use when committing changes. + string commitMessage = 5; + // Paths contains the paths to write hydrated manifests to, along with the manifests and commands to execute. + repeated PathDetails paths = 6; +} + +// PathDetails holds information about hydrated manifests to be written to a particular path in the hydrated manifests +// commit. +message PathDetails { + // Path is the path to write the hydrated manifests to. + string path = 1; + // Manifests contains the manifests to write to the path. + repeated HydratedManifestDetails manifests = 2; + // Commands contains the commands executed when hydrating the manifests. + repeated string commands = 3; +} + +// ManifestDetails contains the hydrated manifests. +message HydratedManifestDetails { + // ManifestJSON is the hydrated manifest as JSON. + string manifestJSON = 1; +} + +// ManifestsResponse is the response to the ManifestsRequest. +message CommitHydratedManifestsResponse { + // HydratedSha is the commit SHA of the hydrated manifests commit. + string hydratedSha = 1; +} + +// CommitService is the service for committing hydrated manifests to a repository. +service CommitService { + // Commit commits hydrated manifests to a repository. + rpc CommitHydratedManifests (CommitHydratedManifestsRequest) returns (CommitHydratedManifestsResponse); +} diff --git a/commitserver/commit/commit_test.go b/commitserver/commit/commit_test.go new file mode 100644 index 0000000000000..77bb9b53482a2 --- /dev/null +++ b/commitserver/commit/commit_test.go @@ -0,0 +1,125 @@ +package commit + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/commit/mocks" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" + gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" +) + +func Test_CommitHydratedManifests(t *testing.T) { + t.Parallel() + + validRequest := &apiclient.CommitHydratedManifestsRequest{ + Repo: &v1alpha1.Repository{ + Repo: "https://github.com/argoproj/argocd-example-apps.git", + }, + TargetBranch: "main", + SyncBranch: "env/test", + CommitMessage: "test commit message", + } + + t.Run("missing repo", func(t *testing.T) { + t.Parallel() + + service, _ := newServiceWithMocks(t) + request := &apiclient.CommitHydratedManifestsRequest{} + _, err := service.CommitHydratedManifests(context.Background(), request) + require.Error(t, err) + assert.ErrorContains(t, err, "repo is required") + }) + + t.Run("missing repo URL", func(t *testing.T) { + t.Parallel() + + service, _ := newServiceWithMocks(t) + request := &apiclient.CommitHydratedManifestsRequest{ + Repo: &v1alpha1.Repository{}, + } + _, err := service.CommitHydratedManifests(context.Background(), request) + require.Error(t, err) + assert.ErrorContains(t, err, "repo URL is required") + }) + + t.Run("missing target branch", func(t *testing.T) { + t.Parallel() + + service, _ := newServiceWithMocks(t) + request := &apiclient.CommitHydratedManifestsRequest{ + Repo: &v1alpha1.Repository{ + Repo: "https://github.com/argoproj/argocd-example-apps.git", + }, + } + _, err := service.CommitHydratedManifests(context.Background(), request) + require.Error(t, err) + assert.ErrorContains(t, err, "target branch is required") + }) + + t.Run("missing sync branch", func(t *testing.T) { + t.Parallel() + + service, _ := newServiceWithMocks(t) + request := &apiclient.CommitHydratedManifestsRequest{ + Repo: &v1alpha1.Repository{ + Repo: "https://github.com/argoproj/argocd-example-apps.git", + }, + TargetBranch: "main", + } + _, err := service.CommitHydratedManifests(context.Background(), request) + require.Error(t, err) + assert.ErrorContains(t, err, "sync branch is required") + }) + + t.Run("failed to create git client", func(t *testing.T) { + t.Parallel() + + service, mockRepoClientFactory := newServiceWithMocks(t) + mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(nil, assert.AnError).Once() + + _, err := service.CommitHydratedManifests(context.Background(), validRequest) + require.Error(t, err) + assert.ErrorIs(t, err, assert.AnError) + }) + + t.Run("happy path", func(t *testing.T) { + t.Parallel() + + service, mockRepoClientFactory := newServiceWithMocks(t) + mockGitClient := gitmocks.NewClient(t) + mockGitClient.On("Init").Return(nil).Once() + mockGitClient.On("Fetch", mock.Anything).Return(nil).Once() + mockGitClient.On("SetAuthor", "Argo CD", "argo-cd@example.com").Return("", nil).Once() + mockGitClient.On("CheckoutOrOrphan", "env/test", false).Return("", nil).Once() + mockGitClient.On("CheckoutOrNew", "main", "env/test", false).Return("", nil).Once() + mockGitClient.On("RemoveContents").Return("", nil).Once() + mockGitClient.On("CommitAndPush", "main", "test commit message").Return("", nil).Once() + mockGitClient.On("CommitSHA").Return("it-worked!", nil).Once() + mockRepoClientFactory.On("NewClient", mock.Anything, mock.Anything).Return(mockGitClient, nil).Once() + + resp, err := service.CommitHydratedManifests(context.Background(), validRequest) + require.NoError(t, err) + require.NotNil(t, resp) + assert.Equal(t, "it-worked!", resp.HydratedSha) + }) +} + +func newServiceWithMocks(t *testing.T) (*Service, *mocks.RepoClientFactory) { + t.Helper() + + metricsServer := metrics.NewMetricsServer() + mockCredsStore := git.NoopCredsStore{} + service := NewService(mockCredsStore, metricsServer) + mockRepoClientFactory := mocks.NewRepoClientFactory(t) + service.repoClientFactory = mockRepoClientFactory + + return service, mockRepoClientFactory +} diff --git a/commitserver/commit/credentialtypehelper.go b/commitserver/commit/credentialtypehelper.go new file mode 100644 index 0000000000000..eda3b8040d497 --- /dev/null +++ b/commitserver/commit/credentialtypehelper.go @@ -0,0 +1,23 @@ +package commit + +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + +// getCredentialType returns the type of credential used by the repository. +func getCredentialType(repo *v1alpha1.Repository) string { + if repo == nil { + return "" + } + if repo.Password != "" { + return "https" + } + if repo.SSHPrivateKey != "" { + return "ssh" + } + if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 { + return "github-app" + } + if repo.GCPServiceAccountKey != "" { + return "cloud-source-repositories" + } + return "" +} diff --git a/commitserver/commit/credentialtypehelper_test.go b/commitserver/commit/credentialtypehelper_test.go new file mode 100644 index 0000000000000..45a013410c20d --- /dev/null +++ b/commitserver/commit/credentialtypehelper_test.go @@ -0,0 +1,62 @@ +package commit + +import ( + "testing" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func TestRepository_GetCredentialType(t *testing.T) { + tests := []struct { + name string + repo *v1alpha1.Repository + want string + }{ + { + name: "Empty Repository", + repo: nil, + want: "", + }, + { + name: "HTTPS Repository", + repo: &v1alpha1.Repository{ + Repo: "foo", + Password: "some-password", + }, + want: "https", + }, + { + name: "SSH Repository", + repo: &v1alpha1.Repository{ + Repo: "foo", + SSHPrivateKey: "some-key", + }, + want: "ssh", + }, + { + name: "GitHub App Repository", + repo: &v1alpha1.Repository{ + Repo: "foo", + GithubAppPrivateKey: "some-key", + GithubAppId: 1, + GithubAppInstallationId: 1, + }, + want: "github-app", + }, + { + name: "Google Cloud Repository", + repo: &v1alpha1.Repository{ + Repo: "foo", + GCPServiceAccountKey: "some-key", + }, + want: "cloud-source-repositories", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getCredentialType(tt.repo); got != tt.want { + t.Errorf("Repository.GetCredentialType() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/commitserver/commit/hydratorhelper.go b/commitserver/commit/hydratorhelper.go new file mode 100644 index 0000000000000..a4fbeb591b53c --- /dev/null +++ b/commitserver/commit/hydratorhelper.go @@ -0,0 +1,145 @@ +package commit + +import ( + "encoding/json" + "fmt" + "os" + "path" + "text/template" + + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io/files" +) + +// WriteForPaths writes the manifests, hydrator.metadata, and README.md files for each path in the provided paths. It +// also writes a root-level hydrator.metadata file containing the repo URL and dry SHA. +func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apiclient.PathDetails) error { + // Write the top-level readme. + err := writeMetadata(rootPath, hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl}) + if err != nil { + return fmt.Errorf("failed to write top-level hydrator metadata: %w", err) + } + + for _, p := range paths { + hydratePath := p.Path + if hydratePath == "." { + hydratePath = "" + } + + var fullHydratePath string + fullHydratePath, err = files.SecureMkdirAll(rootPath, hydratePath, os.ModePerm) + if err != nil { + return fmt.Errorf("failed to create path: %w", err) + } + + // Write the manifests + err = writeManifests(fullHydratePath, p.Manifests) + if err != nil { + return fmt.Errorf("failed to write manifests: %w", err) + } + + // Write hydrator.metadata containing information about the hydration process. + hydratorMetadata := hydratorMetadataFile{ + Commands: p.Commands, + DrySHA: drySha, + RepoURL: repoUrl, + } + err = writeMetadata(fullHydratePath, hydratorMetadata) + if err != nil { + return fmt.Errorf("failed to write hydrator metadata: %w", err) + } + + // Write README + err = writeReadme(fullHydratePath, hydratorMetadata) + if err != nil { + return fmt.Errorf("failed to write readme: %w", err) + } + } + return nil +} + +// writeMetadata writes the metadata to the hydrator.metadata file. +func writeMetadata(dirPath string, metadata hydratorMetadataFile) error { + hydratorMetadataJson, err := json.MarshalIndent(metadata, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal hydrator metadata: %w", err) + } + // No need to use SecureJoin here, as the path is already sanitized. + hydratorMetadataPath := path.Join(dirPath, "hydrator.metadata") + err = os.WriteFile(hydratorMetadataPath, hydratorMetadataJson, os.ModePerm) + if err != nil { + return fmt.Errorf("failed to write hydrator metadata: %w", err) + } + return nil +} + +// writeReadme writes the readme to the README.md file. +func writeReadme(dirPath string, metadata hydratorMetadataFile) error { + readmeTemplate := template.New("readme") + readmeTemplate, err := readmeTemplate.Parse(manifestHydrationReadmeTemplate) + if err != nil { + return fmt.Errorf("failed to parse readme template: %w", err) + } + // Create writer to template into + // No need to use SecureJoin here, as the path is already sanitized. + readmePath := path.Join(dirPath, "README.md") + readmeFile, err := os.Create(readmePath) + if err != nil && !os.IsExist(err) { + return fmt.Errorf("failed to create README file: %w", err) + } + err = readmeTemplate.Execute(readmeFile, metadata) + closeErr := readmeFile.Close() + if closeErr != nil { + log.WithError(closeErr).Error("failed to close README file") + } + if err != nil { + return fmt.Errorf("failed to execute readme template: %w", err) + } + return nil +} + +// writeManifests writes the manifests to the manifest.yaml file, truncating the file if it exists and appending the +// manifests in the order they are provided. +func writeManifests(dirPath string, manifests []*apiclient.HydratedManifestDetails) error { + // If the file exists, truncate it. + // No need to use SecureJoin here, as the path is already sanitized. + manifestPath := path.Join(dirPath, "manifest.yaml") + + file, err := os.OpenFile(manifestPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) + if err != nil { + return fmt.Errorf("failed to open manifest file: %w", err) + } + defer func() { + err := file.Close() + if err != nil { + log.WithError(err).Error("failed to close file") + } + }() + + enc := yaml.NewEncoder(file) + defer func() { + err := enc.Close() + if err != nil { + log.WithError(err).Error("failed to close yaml encoder") + } + }() + enc.SetIndent(2) + + for _, m := range manifests { + obj := &unstructured.Unstructured{} + err = json.Unmarshal([]byte(m.ManifestJSON), obj) + if err != nil { + return fmt.Errorf("failed to unmarshal manifest: %w", err) + } + err = enc.Encode(&obj.Object) + if err != nil { + return fmt.Errorf("failed to encode manifest: %w", err) + } + } + + return nil +} diff --git a/commitserver/commit/hydratorhelper_test.go b/commitserver/commit/hydratorhelper_test.go new file mode 100644 index 0000000000000..51e8adf0c69a5 --- /dev/null +++ b/commitserver/commit/hydratorhelper_test.go @@ -0,0 +1,135 @@ +package commit + +import ( + "encoding/json" + "os" + "path" + "testing" + + securejoin "github.com/cyphar/filepath-securejoin" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" +) + +func TestWriteForPaths(t *testing.T) { + dir := t.TempDir() + + repoUrl := "https://github.com/example/repo" + drySha := "abc123" + paths := []*apiclient.PathDetails{ + { + Path: "path1", + Manifests: []*apiclient.HydratedManifestDetails{ + {ManifestJSON: `{"kind":"Pod","apiVersion":"v1"}`}, + }, + Commands: []string{"command1", "command2"}, + }, + { + Path: "path2", + Manifests: []*apiclient.HydratedManifestDetails{ + {ManifestJSON: `{"kind":"Service","apiVersion":"v1"}`}, + }, + Commands: []string{"command3"}, + }, + } + + err := WriteForPaths(dir, repoUrl, drySha, paths) + require.NoError(t, err) + + // Check if the top-level hydrator.metadata exists and contains the repo URL and dry SHA + topMetadataPath := path.Join(dir, "hydrator.metadata") + topMetadataBytes, err := os.ReadFile(topMetadataPath) + require.NoError(t, err) + + var topMetadata hydratorMetadataFile + err = json.Unmarshal(topMetadataBytes, &topMetadata) + require.NoError(t, err) + assert.Equal(t, repoUrl, topMetadata.RepoURL) + assert.Equal(t, drySha, topMetadata.DrySHA) + + for _, p := range paths { + fullHydratePath, err := securejoin.SecureJoin(dir, p.Path) + require.NoError(t, err) + + // Check if each path directory exists + assert.DirExists(t, fullHydratePath) + + // Check if each path contains a hydrator.metadata file and contains the repo URL + metadataPath := path.Join(fullHydratePath, "hydrator.metadata") + metadataBytes, err := os.ReadFile(metadataPath) + require.NoError(t, err) + + var readMetadata hydratorMetadataFile + err = json.Unmarshal(metadataBytes, &readMetadata) + require.NoError(t, err) + assert.Equal(t, repoUrl, readMetadata.RepoURL) + + // Check if each path contains a README.md file and contains the repo URL + readmePath := path.Join(fullHydratePath, "README.md") + readmeBytes, err := os.ReadFile(readmePath) + require.NoError(t, err) + assert.Contains(t, string(readmeBytes), repoUrl) + + // Check if each path contains a manifest.yaml file and contains the word Pod + manifestPath := path.Join(fullHydratePath, "manifest.yaml") + manifestBytes, err := os.ReadFile(manifestPath) + require.NoError(t, err) + assert.Contains(t, string(manifestBytes), "kind") + } +} + +func TestWriteMetadata(t *testing.T) { + dir := t.TempDir() + + metadata := hydratorMetadataFile{ + RepoURL: "https://github.com/example/repo", + DrySHA: "abc123", + } + + err := writeMetadata(dir, metadata) + require.NoError(t, err) + + metadataPath := path.Join(dir, "hydrator.metadata") + metadataBytes, err := os.ReadFile(metadataPath) + require.NoError(t, err) + + var readMetadata hydratorMetadataFile + err = json.Unmarshal(metadataBytes, &readMetadata) + require.NoError(t, err) + assert.Equal(t, metadata, readMetadata) +} + +func TestWriteReadme(t *testing.T) { + dir := t.TempDir() + + metadata := hydratorMetadataFile{ + RepoURL: "https://github.com/example/repo", + DrySHA: "abc123", + } + + err := writeReadme(dir, metadata) + require.NoError(t, err) + + readmePath := path.Join(dir, "README.md") + readmeBytes, err := os.ReadFile(readmePath) + require.NoError(t, err) + assert.Contains(t, string(readmeBytes), metadata.RepoURL) +} + +func TestWriteManifests(t *testing.T) { + dir := t.TempDir() + + manifests := []*apiclient.HydratedManifestDetails{ + {ManifestJSON: `{"kind":"Pod","apiVersion":"v1"}`}, + } + + err := writeManifests(dir, manifests) + require.NoError(t, err) + + manifestPath := path.Join(dir, "manifest.yaml") + manifestBytes, err := os.ReadFile(manifestPath) + require.NoError(t, err) + assert.Contains(t, string(manifestBytes), "kind") +} diff --git a/commitserver/commit/mocks/RepoClientFactory.go b/commitserver/commit/mocks/RepoClientFactory.go new file mode 100644 index 0000000000000..020c78fdf5f85 --- /dev/null +++ b/commitserver/commit/mocks/RepoClientFactory.go @@ -0,0 +1,59 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + git "github.com/argoproj/argo-cd/v2/util/git" + mock "github.com/stretchr/testify/mock" + + v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +// RepoClientFactory is an autogenerated mock type for the RepoClientFactory type +type RepoClientFactory struct { + mock.Mock +} + +// NewClient provides a mock function with given fields: repo, rootPath +func (_m *RepoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) { + ret := _m.Called(repo, rootPath) + + if len(ret) == 0 { + panic("no return value specified for NewClient") + } + + var r0 git.Client + var r1 error + if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) (git.Client, error)); ok { + return rf(repo, rootPath) + } + if rf, ok := ret.Get(0).(func(*v1alpha1.Repository, string) git.Client); ok { + r0 = rf(repo, rootPath) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(git.Client) + } + } + + if rf, ok := ret.Get(1).(func(*v1alpha1.Repository, string) error); ok { + r1 = rf(repo, rootPath) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewRepoClientFactory creates a new instance of RepoClientFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRepoClientFactory(t interface { + mock.TestingT + Cleanup(func()) +}) *RepoClientFactory { + mock := &RepoClientFactory{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/commitserver/commit/repo_client_factory.go b/commitserver/commit/repo_client_factory.go new file mode 100644 index 0000000000000..f0f3b5c75dbd8 --- /dev/null +++ b/commitserver/commit/repo_client_factory.go @@ -0,0 +1,32 @@ +package commit + +import ( + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/git" +) + +// RepoClientFactory is a factory for creating git clients for a repository. +type RepoClientFactory interface { + NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) +} + +type repoClientFactory struct { + gitCredsStore git.CredsStore + metricsServer *metrics.Server +} + +// NewRepoClientFactory returns a new instance of the repo client factory. +func NewRepoClientFactory(gitCredsStore git.CredsStore, metricsServer *metrics.Server) RepoClientFactory { + return &repoClientFactory{ + gitCredsStore: gitCredsStore, + metricsServer: metricsServer, + } +} + +// NewClient creates a new git client for the repository. +func (r *repoClientFactory) NewClient(repo *v1alpha1.Repository, rootPath string) (git.Client, error) { + gitCreds := repo.GetGitCreds(r.gitCredsStore) + opts := git.WithEventHandlers(metrics.NewGitClientEventHandlers(r.metricsServer)) + return git.NewClientExt(repo.Repo, rootPath, gitCreds, repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy, repo.NoProxy, opts) +} diff --git a/commitserver/metrics/githandlers.go b/commitserver/metrics/githandlers.go new file mode 100644 index 0000000000000..4a960ebd54f34 --- /dev/null +++ b/commitserver/metrics/githandlers.go @@ -0,0 +1,34 @@ +package metrics + +import ( + "time" + + "github.com/argoproj/argo-cd/v2/util/git" +) + +// NewGitClientEventHandlers creates event handlers that update Git related metrics +func NewGitClientEventHandlers(metricsServer *Server) git.EventHandlers { + return git.EventHandlers{ + OnFetch: func(repo string) func() { + startTime := time.Now() + metricsServer.IncGitRequest(repo, GitRequestTypeFetch) + return func() { + metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeFetch, time.Since(startTime)) + } + }, + OnLsRemote: func(repo string) func() { + startTime := time.Now() + metricsServer.IncGitRequest(repo, GitRequestTypeLsRemote) + return func() { + metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeLsRemote, time.Since(startTime)) + } + }, + OnPush: func(repo string) func() { + startTime := time.Now() + metricsServer.IncGitRequest(repo, GitRequestTypePush) + return func() { + metricsServer.ObserveGitRequestDuration(repo, GitRequestTypePush, time.Since(startTime)) + } + }, + } +} diff --git a/commitserver/metrics/metrics.go b/commitserver/metrics/metrics.go new file mode 100644 index 0000000000000..5505add8783b5 --- /dev/null +++ b/commitserver/metrics/metrics.go @@ -0,0 +1,157 @@ +package metrics + +import ( + "net/http" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +// Server is a prometheus server which collects application metrics. +type Server struct { + handler http.Handler + commitPendingRequestsGauge *prometheus.GaugeVec + gitRequestCounter *prometheus.CounterVec + gitRequestHistogram *prometheus.HistogramVec + commitRequestHistogram *prometheus.HistogramVec + userInfoRequestHistogram *prometheus.HistogramVec + commitRequestCounter *prometheus.CounterVec +} + +// GitRequestType is the type of git request +type GitRequestType string + +const ( + // GitRequestTypeLsRemote is a request to list remote refs + GitRequestTypeLsRemote = "ls-remote" + // GitRequestTypeFetch is a request to fetch from remote + GitRequestTypeFetch = "fetch" + // GitRequestTypePush is a request to push to remote + GitRequestTypePush = "push" +) + +// CommitResponseType is the type of response for a commit request +type CommitResponseType string + +const ( + // CommitResponseTypeSuccess is a successful commit request + CommitResponseTypeSuccess CommitResponseType = "success" + // CommitResponseTypeFailure is a failed commit request + CommitResponseTypeFailure CommitResponseType = "failure" +) + +// NewMetricsServer returns a new prometheus server which collects application metrics. +func NewMetricsServer() *Server { + registry := prometheus.NewRegistry() + registry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{})) + registry.MustRegister(collectors.NewGoCollector()) + + commitPendingRequestsGauge := prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "argocd_commitserver_commit_pending_request_total", + Help: "Number of pending commit requests", + }, + []string{"repo"}, + ) + registry.MustRegister(commitPendingRequestsGauge) + + gitRequestCounter := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "argocd_commitserver_git_request_total", + Help: "Number of git requests performed by repo server", + }, + []string{"repo", "request_type"}, + ) + registry.MustRegister(gitRequestCounter) + + gitRequestHistogram := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_commitserver_git_request_duration_seconds", + Help: "Git requests duration seconds.", + Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20}, + }, + []string{"repo", "request_type"}, + ) + registry.MustRegister(gitRequestHistogram) + + commitRequestHistogram := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_commitserver_commit_request_duration_seconds", + Help: "Commit request duration seconds.", + Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20}, + }, + []string{"repo", "response_type"}, + ) + registry.MustRegister(commitRequestHistogram) + + userInfoRequestHistogram := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_commitserver_userinfo_request_duration_seconds", + Help: "Userinfo request duration seconds.", + Buckets: []float64{0.1, 0.25, .5, 1, 2, 4, 10, 20}, + }, + []string{"repo", "credential_type"}, + ) + registry.MustRegister(userInfoRequestHistogram) + + commitRequestCounter := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "argocd_commitserver_commit_request_total", + Help: "Number of commit requests performed handled", + }, + []string{"repo", "response_type"}, + ) + registry.MustRegister(commitRequestCounter) + + return &Server{ + handler: promhttp.HandlerFor(registry, promhttp.HandlerOpts{}), + commitPendingRequestsGauge: commitPendingRequestsGauge, + gitRequestCounter: gitRequestCounter, + gitRequestHistogram: gitRequestHistogram, + commitRequestHistogram: commitRequestHistogram, + userInfoRequestHistogram: userInfoRequestHistogram, + commitRequestCounter: commitRequestCounter, + } +} + +// GetHandler returns the http.Handler for the prometheus server +func (m *Server) GetHandler() http.Handler { + return m.handler +} + +// IncPendingCommitRequest increments the pending commit requests gauge +func (m *Server) IncPendingCommitRequest(repo string) { + m.commitPendingRequestsGauge.WithLabelValues(repo).Inc() +} + +// DecPendingCommitRequest decrements the pending commit requests gauge +func (m *Server) DecPendingCommitRequest(repo string) { + m.commitPendingRequestsGauge.WithLabelValues(repo).Dec() +} + +// IncGitRequest increments the git requests counter +func (m *Server) IncGitRequest(repo string, requestType GitRequestType) { + m.gitRequestCounter.WithLabelValues(repo, string(requestType)).Inc() +} + +// ObserveGitRequestDuration observes the duration of a git request +func (m *Server) ObserveGitRequestDuration(repo string, requestType GitRequestType, duration time.Duration) { + m.gitRequestHistogram.WithLabelValues(repo, string(requestType)).Observe(duration.Seconds()) +} + +// ObserveCommitRequestDuration observes the duration of a commit request +func (m *Server) ObserveCommitRequestDuration(repo string, rt CommitResponseType, duration time.Duration) { + m.commitRequestHistogram.WithLabelValues(repo, string(rt)).Observe(duration.Seconds()) +} + +// ObserveUserInfoRequestDuration observes the duration of a userinfo request +func (m *Server) ObserveUserInfoRequestDuration(repo string, credentialType string, duration time.Duration) { + m.userInfoRequestHistogram.WithLabelValues(repo, credentialType).Observe(duration.Seconds()) +} + +// IncCommitRequest increments the commit request counter +func (m *Server) IncCommitRequest(repo string, rt CommitResponseType) { + m.commitRequestCounter.WithLabelValues(repo, string(rt)).Inc() +} diff --git a/commitserver/server.go b/commitserver/server.go new file mode 100644 index 0000000000000..5e5b63324ca17 --- /dev/null +++ b/commitserver/server.go @@ -0,0 +1,38 @@ +package commitserver + +import ( + "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" + + "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/commitserver/commit" + "github.com/argoproj/argo-cd/v2/commitserver/metrics" + versionpkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/version" + "github.com/argoproj/argo-cd/v2/server/version" + "github.com/argoproj/argo-cd/v2/util/git" +) + +// ArgoCDCommitServer is the server that handles commit requests. +type ArgoCDCommitServer struct { + commitService *commit.Service +} + +// NewServer returns a new instance of the commit server. +func NewServer(gitCredsStore git.CredsStore, metricsServer *metrics.Server) *ArgoCDCommitServer { + return &ArgoCDCommitServer{commitService: commit.NewService(gitCredsStore, metricsServer)} +} + +// CreateGRPC creates a new gRPC server. +func (a *ArgoCDCommitServer) CreateGRPC() *grpc.Server { + server := grpc.NewServer() + versionpkg.RegisterVersionServiceServer(server, version.NewServer(nil, func() (bool, error) { + return true, nil + })) + apiclient.RegisterCommitServiceServer(server, a.commitService) + + healthService := health.NewServer() + grpc_health_v1.RegisterHealthServer(server, healthService) + + return server +} diff --git a/common/common.go b/common/common.go index 79fcdba195eb6..82e0d91f72939 100644 --- a/common/common.go +++ b/common/common.go @@ -26,6 +26,8 @@ const ( const ( // DefaultRepoServerAddr is the gRPC address of the Argo CD repo server DefaultRepoServerAddr = "argocd-repo-server:8081" + // DefaultCommitServerAddr is the gRPC address of the Argo CD commit server + DefaultCommitServerAddr = "argocd-commit-server:8086" // DefaultDexServerAddr is the HTTP address of the Dex OIDC server, which we run a reverse proxy against DefaultDexServerAddr = "argocd-dex-server:5556" // DefaultRedisAddr is the default redis address @@ -62,15 +64,19 @@ const ( DefaultPortArgoCDMetrics = 8082 DefaultPortArgoCDAPIServerMetrics = 8083 DefaultPortRepoServerMetrics = 8084 + DefaultPortCommitServer = 8086 + DefaultPortCommitServerMetrics = 8087 ) // DefaultAddressAPIServer for ArgoCD components const ( - DefaultAddressAdminDashboard = "localhost" - DefaultAddressAPIServer = "0.0.0.0" - DefaultAddressAPIServerMetrics = "0.0.0.0" - DefaultAddressRepoServer = "0.0.0.0" - DefaultAddressRepoServerMetrics = "0.0.0.0" + DefaultAddressAdminDashboard = "localhost" + DefaultAddressAPIServer = "0.0.0.0" + DefaultAddressAPIServerMetrics = "0.0.0.0" + DefaultAddressRepoServer = "0.0.0.0" + DefaultAddressRepoServerMetrics = "0.0.0.0" + DefaultAddressCommitServer = "0.0.0.0" + DefaultAddressCommitServerMetrics = "0.0.0.0" ) // Default paths on the pod's file system @@ -175,13 +181,22 @@ const ( LabelValueSecretTypeRepository = "repository" // LabelValueSecretTypeRepoCreds indicates a secret type of repository credentials LabelValueSecretTypeRepoCreds = "repo-creds" + // LabelValueSecretTypeRepositoryWrite indicates a secret type of repository credentials for writing + LabelValueSecretTypeRepositoryWrite = "repository-write" + // LabelValueSecretTypeSCMCreds indicates a secret type of SCM credentials + LabelValueSecretTypeSCMCreds = "scm-creds" // AnnotationKeyAppInstance is the Argo CD application name is used as the instance name AnnotationKeyAppInstance = "argocd.argoproj.io/tracking-id" + AnnotationInstallationID = "argocd.argoproj.io/installation-id" // AnnotationCompareOptions is a comma-separated list of options for comparison AnnotationCompareOptions = "argocd.argoproj.io/compare-options" + // AnnotationIgnoreHealthCheck when set on an Application's immediate child indicates that its health check + // can be disregarded. + AnnotationIgnoreHealthCheck = "argocd.argoproj.io/ignore-healthcheck" + // AnnotationKeyManagedBy is annotation name which indicates that k8s resource is managed by an application. AnnotationKeyManagedBy = "managed-by" // AnnotationValueManagedByArgoCD is a 'managed-by' annotation value for resources managed by Argo CD @@ -315,7 +330,10 @@ const ( // Constants used by util/clusterauth package const ( ClusterAuthRequestTimeout = 10 * time.Second - BearerTokenTimeout = 30 * time.Second +) + +const ( + BearerTokenTimeout = 30 * time.Second ) const ( @@ -425,8 +443,10 @@ var PermissionDeniedAPIError = status.Error(codes.PermissionDenied, "permission // Redis password consts const ( - DefaultRedisInitialPasswordSecretName = "argocd-redis" - DefaultRedisInitialPasswordKey = "auth" + // RedisInitialCredentials is the name for the argocd kubernetes secret which will have the redis password + RedisInitialCredentials = "argocd-redis" + // RedisInitialCredentialsKey is the key for the argocd kubernetes secret that maps to the redis password + RedisInitialCredentialsKey = "auth" ) /* @@ -435,17 +455,17 @@ SetOptionalRedisPasswordFromKubeConfig sets the optional Redis password if it ex We specify kubeClient as kubernetes.Interface to allow for mocking in tests, but this should be treated as a kubernetes.Clientset param. */ func SetOptionalRedisPasswordFromKubeConfig(ctx context.Context, kubeClient kubernetes.Interface, namespace string, redisOptions *redis.Options) error { - secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, DefaultRedisInitialPasswordSecretName, v1.GetOptions{}) + secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, RedisInitialCredentials, v1.GetOptions{}) if err != nil { - return fmt.Errorf("failed to get secret %s/%s: %w", namespace, DefaultRedisInitialPasswordSecretName, err) + return fmt.Errorf("failed to get secret %s/%s: %w", namespace, RedisInitialCredentials, err) } if secret == nil { - return fmt.Errorf("failed to get secret %s/%s: secret is nil", namespace, DefaultRedisInitialPasswordSecretName) + return fmt.Errorf("failed to get secret %s/%s: secret is nil", namespace, RedisInitialCredentials) } - _, ok := secret.Data[DefaultRedisInitialPasswordKey] + _, ok := secret.Data[RedisInitialCredentialsKey] if !ok { - return fmt.Errorf("secret %s/%s does not contain key %s", namespace, DefaultRedisInitialPasswordSecretName, DefaultRedisInitialPasswordKey) + return fmt.Errorf("secret %s/%s does not contain key %s", namespace, RedisInitialCredentials, RedisInitialCredentialsKey) } - redisOptions.Password = string(secret.Data[DefaultRedisInitialPasswordKey]) + redisOptions.Password = string(secret.Data[RedisInitialCredentialsKey]) return nil } diff --git a/common/common_test.go b/common/common_test.go index 1021a30a14f60..5fc8faf2a2618 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strconv" "testing" "time" @@ -41,7 +42,7 @@ func Test_GRPCKeepAliveMinIsSet(t *testing.T) { // Test invalid env var set for EnvGRPCKeepAliveMin func Test_GRPCKeepAliveMinIncorrectlySet(t *testing.T) { numSeconds := 15 - os.Setenv(EnvGRPCKeepAliveMin, fmt.Sprintf("%d", numSeconds)) + os.Setenv(EnvGRPCKeepAliveMin, strconv.Itoa(numSeconds)) grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() grpcKeepAliveExpectedMin := defaultGRPCKeepAliveEnforcementMinimum @@ -63,24 +64,24 @@ func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { expectedPassword: "password123", expectedErr: "", secret: &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: DefaultRedisInitialPasswordSecretName}, - Data: map[string][]byte{DefaultRedisInitialPasswordKey: []byte("password123")}, + ObjectMeta: metav1.ObjectMeta{Name: RedisInitialCredentials}, + Data: map[string][]byte{RedisInitialCredentialsKey: []byte("password123")}, }, }, { name: "Secret does not exist", namespace: "default", expectedPassword: "", - expectedErr: fmt.Sprintf("failed to get secret default/%s", DefaultRedisInitialPasswordSecretName), + expectedErr: fmt.Sprintf("failed to get secret default/%s", RedisInitialCredentials), secret: nil, }, { name: "Secret exists without correct key", namespace: "default", expectedPassword: "", - expectedErr: fmt.Sprintf("secret default/%s does not contain key %s", DefaultRedisInitialPasswordSecretName, DefaultRedisInitialPasswordKey), + expectedErr: fmt.Sprintf("secret default/%s does not contain key %s", RedisInitialCredentials, RedisInitialCredentialsKey), secret: &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: DefaultRedisInitialPasswordSecretName}, + ObjectMeta: metav1.ObjectMeta{Name: RedisInitialCredentials}, Data: map[string][]byte{}, }, }, @@ -91,7 +92,7 @@ func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { t.Parallel() var ( ctx = context.TODO() - kubeClient = kubefake.NewSimpleClientset() + kubeClient = kubefake.NewClientset() redisOptions = &redis.Options{} ) if tc.secret != nil { @@ -101,8 +102,7 @@ func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { } err := SetOptionalRedisPasswordFromKubeConfig(ctx, kubeClient, tc.namespace, redisOptions) if tc.expectedErr != "" { - require.Error(t, err) - require.Contains(t, err.Error(), tc.expectedErr) + require.ErrorContains(t, err, tc.expectedErr) } else { require.NoError(t, err) } diff --git a/controller/appcontroller.go b/controller/appcontroller.go index e607771de586d..117b4c7d7f7ee 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -42,8 +42,10 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" "github.com/argoproj/argo-cd/v2/common" statecache "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/hydrator" "github.com/argoproj/argo-cd/v2/controller/metrics" "github.com/argoproj/argo-cd/v2/controller/sharding" "github.com/argoproj/argo-cd/v2/pkg/apis/application" @@ -121,6 +123,8 @@ type ApplicationController struct { appComparisonTypeRefreshQueue workqueue.TypedRateLimitingInterface[string] appOperationQueue workqueue.TypedRateLimitingInterface[string] projectRefreshQueue workqueue.TypedRateLimitingInterface[string] + appHydrateQueue workqueue.TypedRateLimitingInterface[string] + hydrationQueue workqueue.TypedRateLimitingInterface[hydrator.HydrationQueueKey] appInformer cache.SharedIndexInformer appLister applisters.ApplicationLister projInformer cache.SharedIndexInformer @@ -130,7 +134,8 @@ type ApplicationController struct { statusHardRefreshTimeout time.Duration statusRefreshJitter time.Duration selfHealTimeout time.Duration - repoClientset apiclient.Clientset + selfHealBackOff *wait.Backoff + syncTimeout time.Duration db db.ArgoDB settingsMgr *settings_util.SettingsManager refreshRequestedApps map[string]CompareWith @@ -145,6 +150,8 @@ type ApplicationController struct { // dynamicClusterDistributionEnabled if disabled deploymentInformer is never initialized dynamicClusterDistributionEnabled bool deploymentInformer informerv1.DeploymentInformer + + hydrator *hydrator.Hydrator } // NewApplicationController creates new instance of ApplicationController. @@ -154,12 +161,15 @@ func NewApplicationController( kubeClientset kubernetes.Interface, applicationClientset appclientset.Interface, repoClientset apiclient.Clientset, + commitClientset commitclient.Clientset, argoCache *appstatecache.Cache, kubectl kube.Kubectl, appResyncPeriod time.Duration, appHardResyncPeriod time.Duration, appResyncJitter time.Duration, selfHealTimeout time.Duration, + selfHealBackoff *wait.Backoff, + syncTimeout time.Duration, repoErrorGracePeriod time.Duration, metricsPort int, metricsCacheExpiration time.Duration, @@ -174,6 +184,7 @@ func NewApplicationController( dynamicClusterDistributionEnabled bool, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts, enableK8sEvent []string, + hydratorEnabled bool, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter) db := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -187,11 +198,12 @@ func NewApplicationController( kubeClientset: kubeClientset, kubectl: kubectl, applicationClientset: applicationClientset, - repoClientset: repoClientset, - appRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_reconciliation_queue"}), - appOperationQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_operation_processing_queue"}), - projectRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "project_reconciliation_queue"}), - appComparisonTypeRefreshQueue: workqueue.NewTypedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), + appRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter[string](rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_reconciliation_queue"}), + appOperationQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter[string](rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_operation_processing_queue"}), + projectRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter[string](rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "project_reconciliation_queue"}), + appComparisonTypeRefreshQueue: workqueue.NewTypedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter[string](rateLimiterConfig)), + appHydrateQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter[string](rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_hydration_queue"}), + hydrationQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter[hydrator.HydrationQueueKey](rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[hydrator.HydrationQueueKey]{Name: "manifest_hydration_queue"}), db: db, statusRefreshTimeout: appResyncPeriod, statusHardRefreshTimeout: appHardResyncPeriod, @@ -201,12 +213,17 @@ func NewApplicationController( auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController, enableK8sEvent), settingsMgr: settingsMgr, selfHealTimeout: selfHealTimeout, + selfHealBackOff: selfHealBackoff, + syncTimeout: syncTimeout, clusterSharding: clusterSharding, projByNameCache: sync.Map{}, applicationNamespaces: applicationNamespaces, dynamicClusterDistributionEnabled: dynamicClusterDistributionEnabled, ignoreNormalizerOpts: ignoreNormalizerOpts, } + if hydratorEnabled { + ctrl.hydrator = hydrator.NewHydrator(&ctrl, appResyncPeriod, commitClientset) + } if kubectlParallelismLimit > 0 { ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit) } @@ -376,7 +393,11 @@ func (projCache *appProjCache) GetAppProject(ctx context.Context) (*appv1.AppPro // getAppProj gets the AppProject for the given Application app. func (ctrl *ApplicationController) getAppProj(app *appv1.Application) (*appv1.AppProject, error) { - projCache, _ := ctrl.projByNameCache.LoadOrStore(app.Spec.GetProject(), ctrl.newAppProjCache(app.Spec.GetProject())) + projCache, _ := ctrl.projByNameCache.Load(app.Spec.GetProject()) + if projCache == nil { + projCache = ctrl.newAppProjCache(app.Spec.GetProject()) + ctrl.projByNameCache.Store(app.Spec.GetProject(), projCache) + } proj, err := projCache.(*appProjCache).GetAppProject(context.TODO()) if err != nil { if apierr.IsNotFound(err) { @@ -627,6 +648,7 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed Message: fmt.Sprintf("Application has %d orphaned resources", len(orphanedNodes)), }} } + ctrl.metricsServer.SetOrphanedResourcesMetric(a, len(orphanedNodes)) a.Status.SetConditions(conditions, map[appv1.ApplicationConditionType]bool{appv1.ApplicationConditionOrphanedResourceWarning: true}) sort.Slice(orphanedNodes, func(i, j int) bool { return orphanedNodes[i].ResourceRef.String() < orphanedNodes[j].ResourceRef.String() @@ -758,7 +780,7 @@ func (ctrl *ApplicationController) hideSecretData(app *appv1.Application, compar resDiff := res.Diff if res.Kind == kube.SecretKind && res.Group == "" { var err error - target, live, err = diff.HideSecretData(res.Target, res.Live) + target, live, err = diff.HideSecretData(res.Target, res.Live, ctrl.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, fmt.Errorf("error hiding secret data: %w", err) } @@ -836,6 +858,8 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int defer ctrl.appComparisonTypeRefreshQueue.ShutDown() defer ctrl.appOperationQueue.ShutDown() defer ctrl.projectRefreshQueue.ShutDown() + defer ctrl.appHydrateQueue.ShutDown() + defer ctrl.hydrationQueue.ShutDown() ctrl.metricsServer.RegisterClustersInfoSource(ctx, ctrl.stateCache) ctrl.RegisterClusterSecretUpdater(ctx) @@ -894,6 +918,19 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int for ctrl.processProjectQueueItem() { } }, time.Second, ctx.Done()) + + if ctrl.hydrator != nil { + go wait.Until(func() { + for ctrl.processAppHydrateQueueItem() { + } + }, time.Second, ctx.Done()) + + go wait.Until(func() { + for ctrl.processHydrationQueueItem() { + } + }, time.Second, ctx.Done()) + } + <-ctx.Done() } @@ -1163,9 +1200,15 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic logCtx.Infof("Resource entries removed from undefined cluster") return nil } - config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, cluster.RESTConfig()) + clusterRESTConfig, err := cluster.RESTConfig() + if err != nil { + return err + } + config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, clusterRESTConfig) if app.CascadedDeletion() { + deletionApproved := app.IsDeletionConfirmed(app.DeletionTimestamp.Time) + logCtx.Infof("Deleting resources") // ApplicationDestination points to a valid cluster, so we may clean up the live objects objs := make([]*unstructured.Unstructured, 0) @@ -1183,6 +1226,10 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic if ctrl.shouldBeDeleted(app, objsMap[k]) { objs = append(objs, objsMap[k]) + if res, ok := app.Status.FindResource(k); ok && res.RequiresDeletionConfirmation && !deletionApproved { + logCtx.Infof("Resource %v requires manual confirmation to delete", k) + return nil + } } } @@ -1361,12 +1408,21 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli // Get rid of sync results and null out previous operation completion time state.SyncResult = nil } + } else if ctrl.syncTimeout != time.Duration(0) && time.Now().After(state.StartedAt.Add(ctrl.syncTimeout)) && !terminating { + state.Phase = synccommon.OperationTerminating + state.Message = "operation is terminating due to timeout" + ctrl.setOperationState(app, state) + logCtx.Infof("Terminating in-progress operation due to timeout. Started at: %v, timeout: %v", state.StartedAt, ctrl.syncTimeout) } else { logCtx.Infof("Resuming in-progress operation. phase: %s, message: %s", state.Phase, state.Message) } } else { state = &appv1.OperationState{Phase: synccommon.OperationRunning, Operation: *app.Operation, StartedAt: metav1.Now()} ctrl.setOperationState(app, state) + if ctrl.syncTimeout != time.Duration(0) { + // Schedule a check during which the timeout would be checked. + ctrl.appOperationQueue.AddAfter(ctrl.toAppKey(app.QualifiedName()), ctrl.syncTimeout) + } logCtx.Infof("Initialized new operation: %v", *app.Operation) } ts.AddCheckpoint("initial_operation_stage_ms") @@ -1618,9 +1674,11 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo project, hasErrors := ctrl.refreshAppConditions(app) ts.AddCheckpoint("refresh_app_conditions_ms") + now := metav1.Now() if hasErrors { app.Status.Sync.Status = appv1.SyncStatusCodeUnknown app.Status.Health.Status = health.HealthStatusUnknown + app.Status.Health.LastTransitionTime = &now patchMs = ctrl.persistAppStatus(origApp, &app.Status) if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), &appv1.ApplicationTree{}); err != nil { @@ -1664,7 +1722,6 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo revisions = append(revisions, revision) sources = append(sources, app.Spec.GetSource()) } - now := metav1.Now() compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, refreshType == appv1.RefreshTypeHard, @@ -1691,7 +1748,8 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo app.Status.Summary = tree.GetSummary(app) } - if project.Spec.SyncWindows.Matches(app).CanSync(false) { + canSync, _ := project.Spec.SyncWindows.Matches(app).CanSync(false) + if canSync { syncErrCond, opMS := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources, compareResult.revisionUpdated) setOpMs = opMS if syncErrCond != nil { @@ -1744,6 +1802,68 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return } +func (ctrl *ApplicationController) processAppHydrateQueueItem() (processNext bool) { + appKey, shutdown := ctrl.appHydrateQueue.Get() + if shutdown { + processNext = false + return + } + processNext = true + defer func() { + if r := recover(); r != nil { + log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) + } + ctrl.appHydrateQueue.Done(appKey) + }() + obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey) + if err != nil { + log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) + return + } + if !exists { + // This happens after app was deleted, but the work queue still had an entry for it. + return + } + origApp, ok := obj.(*appv1.Application) + if !ok { + log.Warnf("Key '%s' in index is not an application", appKey) + return + } + + ctrl.hydrator.ProcessAppHydrateQueueItem(origApp) + + getAppLog(origApp).Debug("Successfully processed app hydrate queue item") + return +} + +func (ctrl *ApplicationController) processHydrationQueueItem() (processNext bool) { + hydrationKey, shutdown := ctrl.hydrationQueue.Get() + if shutdown { + processNext = false + return + } + processNext = true + defer func() { + if r := recover(); r != nil { + log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) + } + ctrl.hydrationQueue.Done(hydrationKey) + }() + + logCtx := log.WithFields(log.Fields{ + "sourceRepoURL": hydrationKey.SourceRepoURL, + "sourceTargetRevision": hydrationKey.SourceTargetRevision, + "destinationBranch": hydrationKey.DestinationBranch, + }) + + logCtx.Debug("Processing hydration queue item") + + ctrl.hydrator.ProcessHydrationQueueItem(hydrationKey) + + logCtx.Debug("Successfully processed hydration queue item") + return +} + func resourceStatusKey(res appv1.ResourceStatus) string { return strings.Join([]string{res.Group, res.Kind, res.Namespace, res.Name}, "/") } @@ -1752,7 +1872,8 @@ func currentSourceEqualsSyncedSource(app *appv1.Application) bool { if app.Spec.HasMultipleSources() { return app.Spec.Sources.Equals(app.Status.Sync.ComparedTo.Sources) } - return app.Spec.Source.Equals(&app.Status.Sync.ComparedTo.Source) + source := app.Spec.GetSource() + return source.Equals(&app.Status.Sync.ComparedTo.Source) } // needRefreshAppStatus answers if application status needs to be refreshed. @@ -1888,6 +2009,7 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new newAnnotations[k] = v } delete(newAnnotations, appv1.AnnotationKeyRefresh) + delete(newAnnotations, appv1.AnnotationKeyHydrate) } patch, modified, err := createMergePatch( &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: orig.GetAnnotations()}, Status: orig.Status}, @@ -1981,6 +2103,9 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * InitiatedBy: appv1.OperationInitiator{Automated: true}, Retry: appv1.RetryStrategy{Limit: 5}, } + if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil { + op.Sync.SelfHealAttemptsCount = app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount + } if app.Spec.SyncPolicy.Retry != nil { op.Retry = *app.Spec.SyncPolicy.Retry } @@ -1998,6 +2123,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * return nil, 0 } else if alreadyAttempted && selfHeal { if shouldSelfHeal, retryAfter := ctrl.shouldSelfHeal(app); shouldSelfHeal { + op.Sync.SelfHealAttemptsCount++ for _, resource := range resources { if resource.Status != appv1.SyncStatusCodeSynced { op.Sync.Resources = append(op.Sync.Resources, appv1.SyncOperationResource{ @@ -2063,7 +2189,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * } // alreadyAttemptedSync returns whether the most recent sync was performed against the -// commitSHA and with the same app source config which are currently set in the app +// commitSHA and with the same app source config which are currently set in the app. func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS []string, hasMultipleSources bool, revisionUpdated bool) (bool, synccommon.OperationPhase) { if app.Status.OperationState == nil || app.Status.OperationState.Operation.Sync == nil || app.Status.OperationState.SyncResult == nil { return false, "" @@ -2088,24 +2214,8 @@ func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS } if hasMultipleSources { - // Ignore differences in target revision, since we already just verified commitSHAs are equal, - // and we do not want to trigger auto-sync due to things like HEAD != master - specSources := app.Spec.Sources.DeepCopy() - syncSources := app.Status.OperationState.SyncResult.Sources.DeepCopy() - for _, source := range specSources { - source.TargetRevision = "" - } - for _, source := range syncSources { - source.TargetRevision = "" - } return reflect.DeepEqual(app.Spec.Sources, app.Status.OperationState.SyncResult.Sources), app.Status.OperationState.Phase } else { - // Ignore differences in target revision, since we already just verified commitSHAs are equal, - // and we do not want to trigger auto-sync due to things like HEAD != master - specSource := app.Spec.Source.DeepCopy() - specSource.TargetRevision = "" - syncResSource := app.Status.OperationState.SyncResult.Source.DeepCopy() - syncResSource.TargetRevision = "" return reflect.DeepEqual(app.Spec.GetSource(), app.Status.OperationState.SyncResult.Source), app.Status.OperationState.Phase } } @@ -2116,10 +2226,24 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, } var retryAfter time.Duration - if app.Status.OperationState.FinishedAt == nil { - retryAfter = ctrl.selfHealTimeout + if ctrl.selfHealBackOff == nil { + if app.Status.OperationState.FinishedAt == nil { + retryAfter = ctrl.selfHealTimeout + } else { + retryAfter = ctrl.selfHealTimeout - time.Since(app.Status.OperationState.FinishedAt.Time) + } } else { - retryAfter = ctrl.selfHealTimeout - time.Since(app.Status.OperationState.FinishedAt.Time) + backOff := *ctrl.selfHealBackOff + backOff.Steps = int(app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount) + var delay time.Duration + for backOff.Steps > 0 { + delay = backOff.Step() + } + if app.Status.OperationState.FinishedAt == nil { + retryAfter = delay + } else { + retryAfter = delay - time.Since(app.Status.OperationState.FinishedAt.Time) + } } return retryAfter <= 0, retryAfter } @@ -2293,6 +2417,9 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar if !newOK || (delay != nil && *delay != time.Duration(0)) { ctrl.appOperationQueue.AddRateLimited(key) } + if ctrl.hydrator != nil { + ctrl.appHydrateQueue.AddRateLimited(newApp.QualifiedName()) + } ctrl.clusterSharding.UpdateApp(newApp) }, DeleteFunc: func(obj interface{}) { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 50fb08042719d..90d7c2ee2e359 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -4,16 +4,20 @@ import ( "context" "encoding/json" "errors" + "fmt" "testing" "time" + clustercache "github.com/argoproj/gitops-engine/pkg/cache" + "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" - - clustercache "github.com/argoproj/gitops-engine/pkg/cache" + "k8s.io/utils/ptr" "github.com/argoproj/argo-cd/v2/common" statecache "github.com/argoproj/argo-cd/v2/controller/cache" @@ -24,6 +28,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,6 +42,7 @@ import ( dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" + mockcommitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient/mocks" mockstatecache "github.com/argoproj/argo-cd/v2/controller/cache/mocks" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" @@ -67,6 +73,7 @@ type fakeData struct { metricsCacheExpiration time.Duration applicationNamespaces []string updateRevisionForPathsResponse *apiclient.UpdateRevisionForPathsResponse + additionalObjs []runtime.Object } type MockKubectl struct { @@ -87,6 +94,10 @@ func (m *MockKubectl) DeleteResource(ctx context.Context, config *rest.Config, g } func newFakeController(data *fakeData, repoErr error) *ApplicationController { + return newFakeControllerWithResync(data, time.Minute, repoErr) +} + +func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration, repoErr error) *ApplicationController { var clust corev1.Secret err := yaml.Unmarshal([]byte(fakeCluster), &clust) if err != nil { @@ -116,6 +127,8 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { mockRepoClientset := mockrepoclient.Clientset{RepoServerServiceClient: &mockRepoClient} + mockCommitClientset := mockcommitclient.Clientset{} + secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-secret", @@ -136,7 +149,9 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { }, Data: data.configMapData, } - kubeClient := fake.NewSimpleClientset(&clust, &cm, &secret) + runtimeObjs := []runtime.Object{&clust, &secret, &cm} + runtimeObjs = append(runtimeObjs, data.additionalObjs...) + kubeClient := fake.NewClientset(runtimeObjs...) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) kubectl := &MockKubectl{Kubectl: &kubetest.MockKubectlCmd{}} ctrl, err := NewApplicationController( @@ -145,15 +160,18 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { kubeClient, appclientset.NewSimpleClientset(data.apps...), &mockRepoClientset, + &mockCommitClientset, appstatecache.NewCache( cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)), 1*time.Minute, ), kubectl, - time.Minute, + appResyncPeriod, time.Hour, time.Second, time.Minute, + nil, + 0, time.Second*10, common.DefaultPortArgoCDMetrics, data.metricsCacheExpiration, @@ -168,6 +186,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { false, normalizers.IgnoreNormalizerOpts{}, testEnableEventList, + false, ) db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) @@ -486,10 +505,23 @@ func newFakeApp() *v1alpha1.Application { return createFakeApp(fakeApp) } +func newFakeAppWithHealthAndTime(status health.HealthStatusCode, timestamp metav1.Time) *v1alpha1.Application { + return createFakeAppWithHealthAndTime(fakeApp, status, timestamp) +} + func newFakeMultiSourceApp() *v1alpha1.Application { return createFakeApp(fakeMultiSourceApp) } +func createFakeAppWithHealthAndTime(testApp string, status health.HealthStatusCode, timestamp metav1.Time) *v1alpha1.Application { + app := createFakeApp(testApp) + app.Status.Health = v1alpha1.HealthStatus{ + Status: status, + LastTransitionTime: ×tamp, + } + return app +} + func newFakeAppWithDestMismatch() *v1alpha1.Application { return createFakeApp(fakeAppWithDestMismatch) } @@ -817,6 +849,7 @@ func TestAutoSyncParameterOverrides(t *testing.T) { // TestFinalizeAppDeletion verifies application deletion func TestFinalizeAppDeletion(t *testing.T) { + now := metav1.Now() defaultProj := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "default", @@ -837,11 +870,9 @@ func TestFinalizeAppDeletion(t *testing.T) { t.Run("CascadingDelete", func(t *testing.T) { app := newFakeApp() app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) + app.DeletionTimestamp = &now app.Spec.Destination.Namespace = test.FakeArgoCDNamespace - appObj := kube.MustToUnstructured(&app) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(appObj): appObj, - }}, nil) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}}, nil) patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) defaultReactor := fakeAppCs.ReactionChain[0] @@ -880,6 +911,7 @@ func TestFinalizeAppDeletion(t *testing.T) { } app := newFakeApp() app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) + app.DeletionTimestamp = &now app.Spec.Destination.Namespace = test.FakeArgoCDNamespace app.Spec.Project = "restricted" appObj := kube.MustToUnstructured(&app) @@ -925,10 +957,8 @@ func TestFinalizeAppDeletion(t *testing.T) { t.Run("DeleteWithDestinationClusterName", func(t *testing.T) { app := newFakeAppWithDestName() app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) - appObj := kube.MustToUnstructured(&app) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(appObj): appObj, - }}, nil) + app.DeletionTimestamp = &now + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}}, nil) patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) defaultReactor := fakeAppCs.ReactionChain[0] @@ -1665,6 +1695,211 @@ func TestUpdateReconciledAt(t *testing.T) { }) } +func TestUpdateHealthStatusTransitionTime(t *testing.T) { + deployment := kube.MustToUnstructured(&v1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "demo", + Namespace: "default", + }, + }) + testCases := []struct { + name string + app *v1alpha1.Application + configMapData map[string]string + expectedStatus health.HealthStatusCode + }{ + { + name: "Degraded to Missing", + app: newFakeAppWithHealthAndTime(health.HealthStatusDegraded, testTimestamp), + configMapData: map[string]string{ + "resource.customizations": ` +apps/Deployment: + health.lua: | + hs = {} + hs.status = "Missing" + hs.message = "" + return hs`, + }, + expectedStatus: health.HealthStatusMissing, + }, + { + name: "Missing to Progressing", + app: newFakeAppWithHealthAndTime(health.HealthStatusMissing, testTimestamp), + configMapData: map[string]string{ + "resource.customizations": ` +apps/Deployment: + health.lua: | + hs = {} + hs.status = "Progressing" + hs.message = "" + return hs`, + }, + expectedStatus: health.HealthStatusProgressing, + }, + { + name: "Progressing to Healthy", + app: newFakeAppWithHealthAndTime(health.HealthStatusProgressing, testTimestamp), + configMapData: map[string]string{ + "resource.customizations": ` +apps/Deployment: + health.lua: | + hs = {} + hs.status = "Healthy" + hs.message = "" + return hs`, + }, + expectedStatus: health.HealthStatusHealthy, + }, + { + name: "Healthy to Degraded", + app: newFakeAppWithHealthAndTime(health.HealthStatusHealthy, testTimestamp), + configMapData: map[string]string{ + "resource.customizations": ` +apps/Deployment: + health.lua: | + hs = {} + hs.status = "Degraded" + hs.message = "" + return hs`, + }, + expectedStatus: health.HealthStatusDegraded, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctrl := newFakeController(&fakeData{ + apps: []runtime.Object{tc.app, &defaultProj}, + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(deployment): deployment, + }, + configMapData: tc.configMapData, + }, nil) + + ctrl.processAppRefreshQueueItem() + apps, err := ctrl.appLister.List(labels.Everything()) + require.NoError(t, err) + assert.NotEmpty(t, apps) + assert.Equal(t, tc.expectedStatus, apps[0].Status.Health.Status) + assert.NotEqual(t, testTimestamp, *apps[0].Status.Health.LastTransitionTime) + }) + } +} + +func TestUpdateHealthStatusProgression(t *testing.T) { + app := newFakeAppWithHealthAndTime(health.HealthStatusDegraded, testTimestamp) + deployment := kube.MustToUnstructured(&v1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "demo", + Namespace: "default", + }, + Status: v1.DeploymentStatus{ + ObservedGeneration: 0, + }, + }) + configMapData := map[string]string{ + "resource.customizations": ` +apps/Deployment: + health.lua: | + hs = {} + hs.status = "" + hs.message = "" + + if obj.metadata ~= nil then + if obj.metadata.labels ~= nil then + current_status = obj.metadata.labels["status"] + if current_status == "Degraded" then + hs.status = "Missing" + elseif current_status == "Missing" then + hs.status = "Progressing" + elseif current_status == "Progressing" then + hs.status = "Healthy" + elseif current_status == "Healthy" then + hs.status = "Degraded" + end + end + end + + return hs`, + } + ctrl := newFakeControllerWithResync(&fakeData{ + apps: []runtime.Object{app, &defaultProj}, + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(deployment): deployment, + }, + configMapData: configMapData, + manifestResponses: []*apiclient.ManifestResponse{ + {}, + {}, + {}, + {}, + }, + }, time.Millisecond*10, nil) + + testCases := []struct { + name string + initialStatus string + expectedStatus health.HealthStatusCode + }{ + { + name: "Degraded to Missing", + initialStatus: "Degraded", + expectedStatus: health.HealthStatusMissing, + }, + { + name: "Missing to Progressing", + initialStatus: "Missing", + expectedStatus: health.HealthStatusProgressing, + }, + { + name: "Progressing to Healthy", + initialStatus: "Progressing", + expectedStatus: health.HealthStatusHealthy, + }, + { + name: "Healthy to Degraded", + initialStatus: "Healthy", + expectedStatus: health.HealthStatusDegraded, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + deployment.SetLabels(map[string]string{"status": tc.initialStatus}) + ctrl.processAppRefreshQueueItem() + apps, err := ctrl.appLister.List(labels.Everything()) + require.NoError(t, err) + if assert.NotEmpty(t, apps) { + assert.Equal(t, tc.expectedStatus, apps[0].Status.Health.Status) + assert.NotEqual(t, testTimestamp, *apps[0].Status.Health.LastTransitionTime) + } + + ctrl.requestAppRefresh(app.Name, nil, nil) + time.Sleep(time.Millisecond * 15) + }) + } +} + func TestProjectErrorToCondition(t *testing.T) { app := newFakeApp() app.Spec.Project = "wrong project" @@ -2143,7 +2378,7 @@ func TestHelmValuesObjectHasReplaceStrategy(t *testing.T) { app, appModified) require.NoError(t, err) - assert.Equal(t, `{"status":{"sync":{"comparedTo":{"source":{"helm":{"valuesObject":{"key":["value-modified1"]}}}}}}}`, string(patch)) + assert.JSONEq(t, `{"status":{"sync":{"comparedTo":{"source":{"helm":{"valuesObject":{"key":["value-modified1"]}}}}}}}`, string(patch)) } func TestAppStatusIsReplaced(t *testing.T) { @@ -2178,13 +2413,206 @@ func TestAppStatusIsReplaced(t *testing.T) { func TestAlreadyAttemptSync(t *testing.T) { app := newFakeApp() - t.Run("same manifest with sync result", func(t *testing.T) { - attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false) - assert.True(t, attempted) + + t.Run("no operation state", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState = nil + attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false) + assert.False(t, attempted) }) - t.Run("different manifest with sync result", func(t *testing.T) { - attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, true) + t.Run("no sync operation", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.Operation.Sync = nil + attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false) assert.False(t, attempted) }) + + t.Run("no sync result", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.SyncResult = nil + attempted, _ := alreadyAttemptedSync(app, "", []string{}, false, false) + assert.False(t, attempted) + }) + + t.Run("single source", func(t *testing.T) { + t.Run("same manifest with sync result", func(t *testing.T) { + attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false) + assert.True(t, attempted) + }) + + t.Run("same manifest with sync result different targetRevision, same SHA", func(t *testing.T) { + // This test represents the case where the user changed a source's target revision to a new branch, but it + // points to the same revision as the old branch. We currently do not consider this as having been "already + // attempted." In the future we may want to short-circuit the auto-sync in these cases. + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Source = v1alpha1.ApplicationSource{TargetRevision: "branch1"} + app.Spec.Source = &v1alpha1.ApplicationSource{TargetRevision: "branch2"} + app.Status.OperationState.SyncResult.Revision = "sha" + attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false) + assert.False(t, attempted) + }) + + t.Run("different manifest with sync result, different SHA", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Revision = "sha1" + attempted, _ := alreadyAttemptedSync(app, "sha2", []string{}, false, true) + assert.False(t, attempted) + }) + + t.Run("different manifest with sync result, same SHA", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Revision = "sha" + attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, true) + assert.True(t, attempted) + }) + }) + + t.Run("multi-source", func(t *testing.T) { + t.Run("same manifest with sync result", func(t *testing.T) { + attempted, _ := alreadyAttemptedSync(app, "", []string{"sha"}, true, false) + assert.True(t, attempted) + }) + + t.Run("same manifest with sync result, different targetRevision, same SHA", func(t *testing.T) { + // This test represents the case where the user changed a source's target revision to a new branch, but it + // points to the same revision as the old branch. We currently do not consider this as having been "already + // attempted." In the future we may want to short-circuit the auto-sync in these cases. + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Sources = []v1alpha1.ApplicationSource{{TargetRevision: "branch1"}} + app.Spec.Sources = []v1alpha1.ApplicationSource{{TargetRevision: "branch2"}} + app.Status.OperationState.SyncResult.Revisions = []string{"sha"} + attempted, _ := alreadyAttemptedSync(app, "", []string{"sha"}, true, false) + assert.False(t, attempted) + }) + + t.Run("different manifest with sync result, different SHAs", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Revisions = []string{"sha_a_=", "sha_b_1"} + attempted, _ := alreadyAttemptedSync(app, "", []string{"sha_a_2", "sha_b_2"}, true, true) + assert.False(t, attempted) + }) + + t.Run("different manifest with sync result, same SHAs", func(t *testing.T) { + app := app.DeepCopy() + app.Status.OperationState.SyncResult.Revisions = []string{"sha_a", "sha_b"} + attempted, _ := alreadyAttemptedSync(app, "", []string{"sha_a", "sha_b"}, true, true) + assert.True(t, attempted) + }) + }) +} + +func assertDurationAround(t *testing.T, expected time.Duration, actual time.Duration) { + t.Helper() + delta := time.Second / 2 + assert.GreaterOrEqual(t, expected, actual-delta) + assert.LessOrEqual(t, expected, actual+delta) +} + +func TestSelfHealExponentialBackoff(t *testing.T) { + ctrl := newFakeController(&fakeData{}, nil) + ctrl.selfHealBackOff = &wait.Backoff{ + Factor: 3, + Duration: 2 * time.Second, + Cap: 5 * time.Minute, + } + + app := &v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{ + OperationState: &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{}, + }, + }, + }, + } + + testCases := []struct { + attempts int64 + finishedAt *metav1.Time + expectedDuration time.Duration + shouldSelfHeal bool + }{{ + attempts: 0, + finishedAt: ptr.To(metav1.Now()), + expectedDuration: 0, + shouldSelfHeal: true, + }, { + attempts: 1, + finishedAt: ptr.To(metav1.Now()), + expectedDuration: 2 * time.Second, + shouldSelfHeal: false, + }, { + attempts: 2, + finishedAt: ptr.To(metav1.Now()), + expectedDuration: 6 * time.Second, + shouldSelfHeal: false, + }, { + attempts: 3, + finishedAt: nil, + expectedDuration: 18 * time.Second, + shouldSelfHeal: false, + }} + + for i := range testCases { + tc := testCases[i] + t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) { + app.Status.OperationState.Operation.Sync.SelfHealAttemptsCount = tc.attempts + app.Status.OperationState.FinishedAt = tc.finishedAt + ok, duration := ctrl.shouldSelfHeal(app) + require.Equal(t, ok, tc.shouldSelfHeal) + assertDurationAround(t, tc.expectedDuration, duration) + }) + } +} + +func TestSyncTimeout(t *testing.T) { + testCases := []struct { + delta time.Duration + expectedPhase synccommon.OperationPhase + expectedMessage string + }{{ + delta: 2 * time.Minute, + expectedPhase: synccommon.OperationFailed, + expectedMessage: "Operation terminated", + }, { + delta: 30 * time.Second, + expectedPhase: synccommon.OperationSucceeded, + expectedMessage: "successfully synced (no more tasks)", + }} + for i := range testCases { + tc := testCases[i] + t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) { + app := newFakeApp() + app.Spec.Project = "default" + app.Operation = &v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "HEAD", + }, + } + ctrl := newFakeController(&fakeData{ + apps: []runtime.Object{app, &defaultProj}, + manifestResponses: []*apiclient.ManifestResponse{{ + Manifests: []string{}, + }}, + }, nil) + + ctrl.syncTimeout = time.Minute + app.Status.OperationState = &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Revision: "HEAD", + }, + }, + Phase: synccommon.OperationRunning, + StartedAt: metav1.NewTime(time.Now().Add(-tc.delta)), + } + ctrl.processRequestedAppOperation(app) + + app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.ObjectMeta.Name, metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, tc.expectedPhase, app.Status.OperationState.Phase) + require.Equal(t, tc.expectedMessage, app.Status.OperationState.Message) + }) + } } diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 170f5118b521a..266c6ab0fd6cc 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -69,6 +69,12 @@ const ( // 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" + // EnvClusterCacheBatchEventsProcessing is the env variable to control whether to enable batch events processing + EnvClusterCacheBatchEventsProcessing = "ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING" + + // EnvClusterCacheEventProcessingInterval is the env variable to control the interval between processing events when BatchEventsProcessing is enabled + EnvClusterCacheEventProcessingInterval = "ARGOCD_CLUSTER_CACHE_EVENT_PROCESSING_INTERVAL" + // AnnotationIgnoreResourceUpdates when set to true on an untracked resource, // argo will apply `ignoreResourceUpdates` configuration on it. AnnotationIgnoreResourceUpdates = "argocd.argoproj.io/ignore-resource-updates" @@ -103,6 +109,12 @@ var ( // clusterCacheRetryUseBackoff specifies whether to use a backoff strategy on cluster cache sync, if retry is enabled clusterCacheRetryUseBackoff bool = false + + // clusterCacheBatchEventsProcessing specifies whether to enable batch events processing + clusterCacheBatchEventsProcessing bool = false + + // clusterCacheEventProcessingInterval specifies the interval between processing events when BatchEventsProcessing is enabled + clusterCacheEventProcessingInterval = 100 * time.Millisecond ) func init() { @@ -114,6 +126,8 @@ func init() { clusterCacheListSemaphoreSize = env.ParseInt64FromEnv(EnvClusterCacheListSemaphore, clusterCacheListSemaphoreSize, 0, math.MaxInt64) clusterCacheAttemptLimit = int32(env.ParseNumFromEnv(EnvClusterCacheAttemptLimit, int(clusterCacheAttemptLimit), 1, math.MaxInt32)) clusterCacheRetryUseBackoff = env.ParseBoolFromEnv(EnvClusterCacheRetryUseBackoff, false) + clusterCacheBatchEventsProcessing = env.ParseBoolFromEnv(EnvClusterCacheBatchEventsProcessing, false) + clusterCacheEventProcessingInterval = env.ParseDurationFromEnv(EnvClusterCacheEventProcessingInterval, clusterCacheEventProcessingInterval, 0, math.MaxInt64) } type LiveStateCache interface { @@ -197,6 +211,7 @@ type cacheSettings struct { clusterSettings clustercache.Settings appInstanceLabelKey string trackingMethod appv1.TrackingMethod + installationID string // resourceOverrides provides a list of ignored differences to ignore watched resource updates resourceOverrides map[string]appv1.ResourceOverride @@ -225,6 +240,10 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) { if err != nil { return nil, err } + installationID, err := c.settingsMgr.GetInstallationID() + if err != nil { + return nil, err + } resourceUpdatesOverrides, err := c.settingsMgr.GetIgnoreResourceUpdatesOverrides() if err != nil { return nil, err @@ -246,7 +265,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) { ResourcesFilter: resourcesFilter, } - return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr), resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil + return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil } func asResourceNode(r *clustercache.Resource) appv1.ResourceNode { @@ -490,7 +509,10 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e return nil, fmt.Errorf("error getting value for %v: %w", settings.RespectRBAC, err) } - clusterCacheConfig := cluster.RESTConfig() + clusterCacheConfig, err := cluster.RESTConfig() + if err != nil { + return nil, fmt.Errorf("error getting cluster RESTConfig: %w", err) + } // Controller dynamically fetches all resource types available on the cluster // using a discovery API that may contain deprecated APIs. // This causes log flooding when managing a large number of clusters. @@ -523,7 +545,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e res.Health, _ = health.GetResourceHealth(un, cacheSettings.clusterSettings.ResourceHealthOverride) - appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, cacheSettings.trackingMethod) + appName := c.resourceTracking.GetAppName(un, cacheSettings.appInstanceLabelKey, cacheSettings.trackingMethod, cacheSettings.installationID) if isRoot && appName != "" { res.AppName = appName } @@ -546,6 +568,8 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e clustercache.SetLogr(logutils.NewLogrusLogger(log.WithField("server", cluster.Server))), clustercache.SetRetryOptions(clusterCacheAttemptLimit, clusterCacheRetryUseBackoff, isRetryableError), clustercache.SetRespectRBAC(respectRBAC), + clustercache.SetBatchEventsProcessing(clusterCacheBatchEventsProcessing), + clustercache.SetEventProcessingInterval(clusterCacheEventProcessingInterval), } clusterCache = clustercache.NewClusterCache(clusterCacheConfig, clusterCacheOpts...) @@ -600,6 +624,10 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e c.metricsServer.IncClusterEventsCount(cluster.Server, gvk.Group, gvk.Kind) }) + _ = clusterCache.OnProcessEventsHandler(func(duration time.Duration, processedEventsNumber int) { + c.metricsServer.ObserveResourceEventsProcessingDuration(cluster.Server, duration, processedEventsNumber) + }) + c.clusters[server] = clusterCache return clusterCache, nil @@ -821,7 +849,12 @@ func (c *liveStateCache) handleModEvent(oldCluster *appv1.Cluster, newCluster *a var updateSettings []clustercache.UpdateSettingsFunc if !reflect.DeepEqual(oldCluster.Config, newCluster.Config) { - updateSettings = append(updateSettings, clustercache.SetConfig(newCluster.RESTConfig())) + newClusterRESTConfig, err := newCluster.RESTConfig() + if err == nil { + updateSettings = append(updateSettings, clustercache.SetConfig(newClusterRESTConfig)) + } else { + log.Errorf("error getting cluster REST config: %v", err) + } } if !reflect.DeepEqual(oldCluster.Namespaces, newCluster.Namespaces) { updateSettings = append(updateSettings, clustercache.SetNamespaces(newCluster.Namespaces)) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 63935a1e453f4..652b4b5549ccc 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -140,7 +140,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { } db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) - fakeClient := fake.NewSimpleClientset() + fakeClient := fake.NewClientset() settingsMgr := argosettings.NewSettingsManager(context.TODO(), fakeClient, "argocd") liveStateCacheLock := sync.RWMutex{} gitopsEngineClusterCache := &mocks.ClusterCache{} diff --git a/controller/cache/info.go b/controller/cache/info.go index 0734e2d118678..635000e688ce3 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -66,6 +66,8 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa switch gvk.Kind { case "VirtualService": populateIstioVirtualServiceInfo(un, res) + case "ServiceEntry": + populateIstioServiceEntryInfo(un, res) } } } @@ -278,6 +280,48 @@ func populateIstioVirtualServiceInfo(un *unstructured.Unstructured, res *Resourc res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, ExternalURLs: urls} } +func populateIstioServiceEntryInfo(un *unstructured.Unstructured, res *ResourceInfo) { + targetLabels, ok, err := unstructured.NestedStringMap(un.Object, "spec", "workloadSelector", "labels") + if err != nil { + return + } + if !ok { + return + } + res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{ + TargetLabels: targetLabels, + TargetRefs: []v1alpha1.ResourceRef{{ + Kind: kube.PodKind, + }}, + } +} + +func isPodInitializedConditionTrue(status *v1.PodStatus) bool { + for _, condition := range status.Conditions { + if condition.Type != v1.PodInitialized { + continue + } + + return condition.Status == v1.ConditionTrue + } + return false +} + +func isRestartableInitContainer(initContainer *v1.Container) bool { + if initContainer == nil { + return false + } + if initContainer.RestartPolicy == nil { + return false + } + + return *initContainer.RestartPolicy == v1.ContainerRestartPolicyAlways +} + +func isPodPhaseTerminal(phase v1.PodPhase) bool { + return phase == v1.PodFailed || phase == v1.PodSucceeded +} + func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { pod := v1.Pod{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &pod) @@ -288,7 +332,8 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { totalContainers := len(pod.Spec.Containers) readyContainers := 0 - reason := string(pod.Status.Phase) + podPhase := pod.Status.Phase + reason := string(podPhase) if pod.Status.Reason != "" { reason = pod.Status.Reason } @@ -306,6 +351,21 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { res.Images = append(res.Images, image) } + // If the Pod carries {type:PodScheduled, reason:SchedulingGated}, set reason to 'SchedulingGated'. + for _, condition := range pod.Status.Conditions { + if condition.Type == v1.PodScheduled && condition.Reason == v1.PodReasonSchedulingGated { + reason = v1.PodReasonSchedulingGated + } + } + + initContainers := make(map[string]*v1.Container) + for i := range pod.Spec.InitContainers { + initContainers[pod.Spec.InitContainers[i].Name] = &pod.Spec.InitContainers[i] + if isRestartableInitContainer(&pod.Spec.InitContainers[i]) { + totalContainers++ + } + } + initializing := false for i := range pod.Status.InitContainerStatuses { container := pod.Status.InitContainerStatuses[i] @@ -313,6 +373,12 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { switch { case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0: continue + case isRestartableInitContainer(initContainers[container.Name]) && + container.Started != nil && *container.Started: + if container.Ready { + readyContainers++ + } + continue case container.State.Terminated != nil: // initialization is failed if len(container.State.Terminated.Reason) == 0 { @@ -334,8 +400,7 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { } break } - if !initializing { - restarts = 0 + if !initializing || isPodInitializedConditionTrue(&pod.Status) { hasRunning := false for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- { container := pod.Status.ContainerStatuses[i] @@ -370,7 +435,9 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { // and https://github.com/kubernetes/kubernetes/issues/90358#issuecomment-617859364 if pod.DeletionTimestamp != nil && pod.Status.Reason == "NodeLost" { reason = "Unknown" - } else if pod.DeletionTimestamp != nil { + // If the pod is being deleted and the pod phase is not succeeded or failed, set the reason to "Terminating". + // See https://github.com/kubernetes/kubectl/issues/1595#issuecomment-2080001023 + } else if pod.DeletionTimestamp != nil && !isPodPhaseTerminal(podPhase) { reason = "Terminating" } @@ -384,7 +451,7 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Node", Value: pod.Spec.NodeName}) res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Containers", Value: fmt.Sprintf("%d/%d", readyContainers, totalContainers)}) if restarts > 0 { - res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Restart Count", Value: fmt.Sprintf("%d", restarts)}) + res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Restart Count", Value: strconv.Itoa(restarts)}) } var urls []string diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go index da47f8e498c63..db58d209f19b8 100644 --- a/controller/cache/info_test.go +++ b/controller/cache/info_test.go @@ -246,10 +246,40 @@ spec: - destination: host: service `) + + testIstioServiceEntry = strToUnstructured(` +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: echo +spec: + exportTo: + - '*' + hosts: + - echo.internal + location: MESH_INTERNAL + ports: + - name: http + number: 80 + protocol: HTTP + targetPort: 5678 + resolution: DNS + + workloadSelector: + labels: + app.kubernetes.io/name: echo-2 +`) ) +// These tests are equivalent to tests in ui/src/app/applications/components/utils.test.tsx. If you update tests here, +// please make sure to update the equivalent tests in the UI. func TestGetPodInfo(t *testing.T) { - pod := strToUnstructured(` + t.Parallel() + + t.Run("TestGetPodInfo", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` apiVersion: v1 kind: Pod metadata: @@ -271,18 +301,589 @@ func TestGetPodInfo(t *testing.T) { memory: 128Mi `) - info := &ResourceInfo{} - populateNodeInfo(pod, info, []string{}) - assert.Equal(t, []v1alpha1.InfoItem{ - {Name: "Node", Value: "minikube"}, - {Name: "Containers", Value: "0/1"}, - }, info.Info) - assert.Equal(t, []string{"bar"}, info.Images) - assert.Equal(t, &PodInfo{ - NodeName: "minikube", - ResourceRequests: v1.ResourceList{v1.ResourceMemory: resource.MustParse("128Mi")}, - }, info.PodInfo) - assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, info.NetworkingInfo) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + assert.Equal(t, []string{"bar"}, info.Images) + assert.Equal(t, &PodInfo{ + NodeName: "minikube", + ResourceRequests: v1.ResourceList{v1.ResourceMemory: resource.MustParse("128Mi")}, + }, info.PodInfo) + assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{Labels: map[string]string{"app": "guestbook"}}, info.NetworkingInfo) + }) + + t.Run("TestGetPodWithInitialContainerInfo", func(t *testing.T) { + pod := strToUnstructured(` + apiVersion: "v1" + kind: "Pod" + metadata: + labels: + app: "app-with-initial-container" + name: "app-with-initial-container-5f46976fdb-vd6rv" + namespace: "default" + ownerReferences: + - apiVersion: "apps/v1" + kind: "ReplicaSet" + name: "app-with-initial-container-5f46976fdb" + spec: + containers: + - image: "alpine:latest" + imagePullPolicy: "Always" + name: "app-with-initial-container" + initContainers: + - image: "alpine:latest" + imagePullPolicy: "Always" + name: "app-with-initial-container-logshipper" + nodeName: "minikube" + status: + containerStatuses: + - image: "alpine:latest" + name: "app-with-initial-container" + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: "2024-10-08T08:44:25Z" + initContainerStatuses: + - image: "alpine:latest" + name: "app-with-initial-container-logshipper" + ready: true + restartCount: 0 + started: false + state: + terminated: + exitCode: 0 + reason: "Completed" + phase: "Running" +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Running"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "1/1"}, + }, info.Info) + }) + + t.Run("TestGetPodInfoWithSidecar", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + labels: + app: app-with-sidecar + name: app-with-sidecar-6664cc788c-lqlrp + namespace: default + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: app-with-sidecar-6664cc788c + spec: + containers: + - image: 'docker.m.daocloud.io/library/alpine:latest' + imagePullPolicy: Always + name: app-with-sidecar + initContainers: + - image: 'docker.m.daocloud.io/library/alpine:latest' + imagePullPolicy: Always + name: logshipper + restartPolicy: Always + nodeName: minikube + status: + containerStatuses: + - image: 'docker.m.daocloud.io/library/alpine:latest' + name: app-with-sidecar + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-08T08:39:43Z' + initContainerStatuses: + - image: 'docker.m.daocloud.io/library/alpine:latest' + name: logshipper + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-08T08:39:40Z' + phase: Running +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Running"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "2/2"}, + }, info.Info) + }) + + t.Run("TestGetPodInfoWithInitialContainer", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + generateName: myapp-long-exist-56b7d8794d- + labels: + app: myapp-long-exist + name: myapp-long-exist-56b7d8794d-pbgrd + namespace: linghao + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: myapp-long-exist-56b7d8794d + spec: + containers: + - image: alpine:latest + imagePullPolicy: Always + name: myapp-long-exist + initContainers: + - image: alpine:latest + imagePullPolicy: Always + name: myapp-long-exist-logshipper + nodeName: minikube + status: + containerStatuses: + - image: alpine:latest + name: myapp-long-exist + ready: false + restartCount: 0 + started: false + state: + waiting: + reason: PodInitializing + initContainerStatuses: + - image: alpine:latest + name: myapp-long-exist-logshipper + ready: false + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-09T08:03:45Z' + phase: Pending + startTime: '2024-10-09T08:02:39Z' +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Init:0/1"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test pod has 2 restartable init containers, the first one running but not started. + t.Run("TestGetPodInfoWithRestartableInitContainer", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test1 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Pending + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: false + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + waiting: {} + started: false + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} + conditions: + - type: ContainersReady + status: "False" + - type: Initialized + status: "False" +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Init:0/2"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/3"}, + {Name: "Restart Count", Value: "3"}, + }, info.Info) + }) + + // Test pod has 2 restartable init containers, the first one started and the second one running but not started. + t.Run("TestGetPodInfoWithPartiallyStartedInitContainers", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test1 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Pending + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: true + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + running: {} + started: false + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} + conditions: + - type: ContainersReady + status: "False" + - type: Initialized + status: "False" +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Init:1/2"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/3"}, + {Name: "Restart Count", Value: "3"}, + }, info.Info) + }) + + // Test pod has 2 restartable init containers started and 1 container running + t.Run("TestGetPodInfoWithStartedInitContainers", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test2 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Running + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: true + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + running: {} + started: true + containerStatuses: + - ready: true + restartCount: 4 + state: + running: {} + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + conditions: + - type: ContainersReady + status: "False" + - type: Initialized + status: "True" +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Running"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "1/3"}, + {Name: "Restart Count", Value: "7"}, + }, info.Info) + }) + + // Test pod has 1 init container restarting and 1 container not running + t.Run("TestGetPodInfoWithNormalInitContainer", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test7 + spec: + initContainers: + - name: init-container + containers: + - name: main-container + nodeName: minikube + status: + phase: podPhase + initContainerStatuses: + - ready: false + restartCount: 3 + state: + running: {} + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with the actual time + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} +`) + + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Init:0/1"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + {Name: "Restart Count", Value: "3"}, + }, info.Info) + }) + + // Test pod condition succeed + t.Run("TestPodConditionSucceeded", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test8 + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Succeeded + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Completed + exitCode: 0 +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Completed"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test pod condition failed + t.Run("TestPodConditionFailed", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test9 + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Failed + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Error + exitCode: 1 +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Error"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test pod condition succeed with deletion + t.Run("TestPodConditionSucceededWithDeletion", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test10 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Succeeded + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Completed + exitCode: 0 +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Completed"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test pod condition running with deletion + t.Run("TestPodConditionRunningWithDeletion", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test11 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Running + containerStatuses: + - ready: false + restartCount: 0 + state: + running: {} +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Terminating"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test pod condition pending with deletion + t.Run("TestPodConditionPendingWithDeletion", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test12 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Pending +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "Terminating"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/1"}, + }, info.Info) + }) + + // Test PodScheduled condition with reason SchedulingGated + t.Run("TestPodScheduledWithSchedulingGated", func(t *testing.T) { + t.Parallel() + + pod := strToUnstructured(` + apiVersion: v1 + kind: Pod + metadata: + name: test13 + spec: + nodeName: minikube + containers: + - name: container1 + - name: container2 + status: + phase: podPhase + conditions: + - type: PodScheduled + status: "False" + reason: SchedulingGated +`) + info := &ResourceInfo{} + populateNodeInfo(pod, info, []string{}) + assert.Equal(t, []v1alpha1.InfoItem{ + {Name: "Status Reason", Value: "SchedulingGated"}, + {Name: "Node", Value: "minikube"}, + {Name: "Containers", Value: "0/2"}, + }, info.Info) + }) } func TestGetNodeInfo(t *testing.T) { @@ -355,6 +956,21 @@ func TestGetIstioVirtualServiceInfo(t *testing.T) { }) } +func TestGetIstioServiceEntryInfo(t *testing.T) { + info := &ResourceInfo{} + populateNodeInfo(testIstioServiceEntry, info, []string{}) + assert.Empty(t, info.Info) + require.NotNil(t, info.NetworkingInfo) + require.NotNil(t, info.NetworkingInfo.TargetRefs) + assert.Contains(t, info.NetworkingInfo.TargetRefs, v1alpha1.ResourceRef{ + Kind: kube.PodKind, + }) + + assert.Equal(t, map[string]string{ + "app.kubernetes.io/name": "echo-2", + }, info.NetworkingInfo.TargetLabels) +} + func TestGetIngressInfo(t *testing.T) { tests := []struct { Ingress *unstructured.Unstructured diff --git a/controller/clusterinfoupdater_test.go b/controller/clusterinfoupdater_test.go index 989ac630d528a..6dc10d9db3e30 100644 --- a/controller/clusterinfoupdater_test.go +++ b/controller/clusterinfoupdater_test.go @@ -67,7 +67,7 @@ func TestClusterSecretUpdater(t *testing.T) { "server.secretkey": nil, }, } - kubeclientset := fake.NewSimpleClientset(emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) appclientset := appsfake.NewSimpleClientset() appInformer := appinformers.NewApplicationInformer(appclientset, "", time.Minute, cache.Indexers{}) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) diff --git a/controller/health.go b/controller/health.go index f713a574f57d3..ece586c00b089 100644 --- a/controller/health.go +++ b/controller/health.go @@ -8,8 +8,10 @@ import ( "github.com/argoproj/gitops-engine/pkg/sync/ignore" kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube" log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/lua" @@ -19,11 +21,15 @@ import ( func setApplicationHealth(resources []managedResource, statuses []appv1.ResourceStatus, resourceOverrides map[string]appv1.ResourceOverride, app *appv1.Application, persistResourceHealth bool) (*appv1.HealthStatus, error) { var savedErr error var errCount uint + appHealth := appv1.HealthStatus{Status: health.HealthStatusHealthy} for i, res := range resources { if res.Target != nil && hookutil.Skip(res.Target) { continue } + if res.Target != nil && res.Target.GetAnnotations() != nil && res.Target.GetAnnotations()[common.AnnotationIgnoreHealthCheck] == "true" { + continue + } if res.Live != nil && (hookutil.IsHook(res.Live) || ignore.Ignore(res.Live)) { continue @@ -76,6 +82,13 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource } if persistResourceHealth { app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline + // if the status didn't change, don't update the timestamp + if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil { + appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime + } else { + now := metav1.Now() + appHealth.LastTransitionTime = &now + } } else { app.Status.ResourceHealthSource = appv1.ResourceHealthLocationAppTree } diff --git a/controller/health_test.go b/controller/health_test.go index efaf4b2a8fc80..3cc3f8d67d816 100644 --- a/controller/health_test.go +++ b/controller/health_test.go @@ -1,8 +1,10 @@ package controller import ( + "fmt" "os" "testing" + "time" "github.com/argoproj/gitops-engine/pkg/health" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" @@ -19,7 +21,16 @@ import ( "github.com/argoproj/argo-cd/v2/util/lua" ) -var app = &appv1.Application{} +var ( + app = &appv1.Application{ + Status: appv1.ApplicationStatus{ + Health: appv1.HealthStatus{ + LastTransitionTime: &metav1.Time{Time: time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC)}, + }, + }, + } + testTimestamp = metav1.Time{Time: time.Date(2020, time.January, 1, 12, 0, 0, 0, time.UTC)} +) func initStatuses(resources []managedResource) []appv1.ResourceStatus { statuses := make([]appv1.ResourceStatus, len(resources)) @@ -56,15 +67,35 @@ func TestSetApplicationHealth(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) require.NoError(t, err) assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) - assert.Equal(t, health.HealthStatusHealthy, resourceStatuses[0].Health.Status) assert.Equal(t, health.HealthStatusDegraded, resourceStatuses[1].Health.Status) + // Health.LastTransitionTime is set only for app health and not at individual resource level + assert.NotNil(t, healthStatus.LastTransitionTime) + assert.Nil(t, resourceStatuses[0].Health.LastTransitionTime) + assert.Nil(t, resourceStatuses[1].Health.LastTransitionTime) + previousLastTransitionTime := healthStatus.LastTransitionTime + app.Status.Health = *healthStatus // now mark the job as a hook and retry. it should ignore the hook and consider the app healthy failedJob.SetAnnotations(map[string]string{synccommon.AnnotationKeyHook: "PreSync"}) healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + // change in health, timestamp should change + assert.NotEqual(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime) + previousLastTransitionTime = healthStatus.LastTransitionTime + app.Status.Health = *healthStatus + + // now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target. + // The app is considered healthy + failedJob.SetAnnotations(nil) + failedJobIgnoreHealthcheck := resourceFromFile("./testdata/job-failed-ignore-healthcheck.yaml") + resources[1].Target = &failedJobIgnoreHealthcheck + healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true) + require.NoError(t, err) + assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) + // no change in health, timestamp shouldn't change + assert.Equal(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime) } func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) { @@ -93,6 +124,41 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) require.NoError(t, err) assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) + assert.False(t, healthStatus.LastTransitionTime.IsZero()) +} + +func TestSetApplicationHealth_HealthImproves(t *testing.T) { + testCases := []struct { + oldStatus health.HealthStatusCode + newStatus health.HealthStatusCode + }{ + {health.HealthStatusUnknown, health.HealthStatusDegraded}, + {health.HealthStatusDegraded, health.HealthStatusProgressing}, + {health.HealthStatusMissing, health.HealthStatusProgressing}, + {health.HealthStatusProgressing, health.HealthStatusSuspended}, + {health.HealthStatusSuspended, health.HealthStatusHealthy}, + } + + for _, tc := range testCases { + overrides := lua.ResourceHealthOverrides{ + lua.GetConfigMapKey(schema.FromAPIVersionAndKind("v1", "Pod")): appv1.ResourceOverride{ + HealthLua: fmt.Sprintf("hs = {}\nhs.status = %q\nhs.message = \"\"return hs", tc.newStatus), + }, + } + + runningPod := resourceFromFile("./testdata/pod-running-restart-always.yaml") + resources := []managedResource{{ + Group: "", Version: "v1", Kind: "Pod", Live: &runningPod, + }} + resourceStatuses := initStatuses(resources) + + t.Run(string(fmt.Sprintf("%s to %s", tc.oldStatus, tc.newStatus)), func(t *testing.T) { + healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) + require.NoError(t, err) + assert.Equal(t, tc.newStatus, healthStatus.Status) + assert.NotEqual(t, testTimestamp, *healthStatus.LastTransitionTime) + }) + } } func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { @@ -118,6 +184,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { }, app, true) require.NoError(t, err) assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) + assert.False(t, healthStatus.LastTransitionTime.IsZero()) }) } diff --git a/controller/hook.go b/controller/hook.go index 5c391114ab9bb..b0fd8ebb039b4 100644 --- a/controller/hook.go +++ b/controller/hook.go @@ -51,7 +51,7 @@ func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Applicat revisions = append(revisions, src.TargetRevision) } - targets, _, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj, false) + targets, _, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj, false, true) if err != nil { return false, err } diff --git a/controller/hydrator/hydrator.go b/controller/hydrator/hydrator.go new file mode 100644 index 0000000000000..6d1fe10ffc7cd --- /dev/null +++ b/controller/hydrator/hydrator.go @@ -0,0 +1,347 @@ +package hydrator + +import ( + "context" + "encoding/json" + "fmt" + "time" + + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + commitclient "github.com/argoproj/argo-cd/v2/commitserver/apiclient" + "github.com/argoproj/argo-cd/v2/controller/utils" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + argoio "github.com/argoproj/argo-cd/v2/util/io" +) + +// Dependencies is the interface for the dependencies of the Hydrator. It serves two purposes: 1) it prevents the +// hydrator from having direct access to the app controller, and 2) it allows for easy mocking of dependencies in tests. +// If you add something here, be sure that it is something the app controller needs to provide to the hydrator. +type Dependencies interface { + // TODO: determine if we actually need to get the app, or if all the stuff we need the app for is done already on + // the app controller side. + GetProcessableAppProj(app *appv1.Application) (*appv1.AppProject, error) + GetProcessableApps() (*appv1.ApplicationList, error) + GetRepoObjs(app *appv1.Application, source appv1.ApplicationSource, revision string, project *appv1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) + GetWriteCredentials(ctx context.Context, repoURL string, project string) (*appv1.Repository, error) + RequestAppRefresh(appName string) + // TODO: only allow access to the hydrator status + PersistAppHydratorStatus(orig *appv1.Application, newStatus *appv1.SourceHydratorStatus) + AddHydrationQueueItem(key HydrationQueueKey) +} + +type Hydrator struct { + dependencies Dependencies + statusRefreshTimeout time.Duration + commitClientset commitclient.Clientset +} + +func NewHydrator(dependencies Dependencies, statusRefreshTimeout time.Duration, commitClientset commitclient.Clientset) *Hydrator { + return &Hydrator{ + dependencies: dependencies, + statusRefreshTimeout: statusRefreshTimeout, + commitClientset: commitClientset, + } +} + +func (h *Hydrator) ProcessAppHydrateQueueItem(origApp *appv1.Application) { + origApp = origApp.DeepCopy() + app := origApp.DeepCopy() + + if app.Spec.SourceHydrator == nil { + return + } + + logCtx := utils.GetAppLog(app) + + logCtx.Debug("Processing app hydrate queue item") + + // TODO: don't reuse statusRefreshTimeout. Create a new timeout for hydration. + needsHydration, reason := appNeedsHydration(origApp, h.statusRefreshTimeout) + if !needsHydration { + return + } + + logCtx.WithField("reason", reason).Info("Hydrating app") + + app.Status.SourceHydrator.CurrentOperation = &appv1.HydrateOperation{ + StartedAt: metav1.Now(), + FinishedAt: nil, + Phase: appv1.HydrateOperationPhaseHydrating, + SourceHydrator: *app.Spec.SourceHydrator, + } + h.dependencies.PersistAppHydratorStatus(origApp, &app.Status.SourceHydrator) + origApp.Status.SourceHydrator = app.Status.SourceHydrator + h.dependencies.AddHydrationQueueItem(getHydrationQueueKey(app)) + + logCtx.Debug("Successfully processed app hydrate queue item") +} + +func getHydrationQueueKey(app *appv1.Application) HydrationQueueKey { + destinationBranch := app.Spec.SourceHydrator.SyncSource.TargetBranch + if app.Spec.SourceHydrator.HydrateTo != nil { + destinationBranch = app.Spec.SourceHydrator.HydrateTo.TargetBranch + } + key := HydrationQueueKey{ + SourceRepoURL: app.Spec.SourceHydrator.DrySource.RepoURL, + SourceTargetRevision: app.Spec.SourceHydrator.DrySource.TargetRevision, + DestinationBranch: destinationBranch, + } + return key +} + +type HydrationQueueKey struct { + SourceRepoURL string + SourceTargetRevision string + DestinationBranch string +} + +// uniqueHydrationDestination is used to detect duplicate hydrate destinations. +type uniqueHydrationDestination struct { + sourceRepoURL string + sourceTargetRevision string + destinationBranch string + destinationPath string +} + +func (h *Hydrator) ProcessHydrationQueueItem(hydrationKey HydrationQueueKey) (processNext bool) { + logCtx := log.WithFields(log.Fields{ + "sourceRepoURL": hydrationKey.SourceRepoURL, + "sourceTargetRevision": hydrationKey.SourceTargetRevision, + "destinationBranch": hydrationKey.DestinationBranch, + }) + + relevantApps, drySHA, hydratedSHA, err := h.hydrateAppsLatestCommit(logCtx, hydrationKey) + if drySHA != "" { + logCtx = logCtx.WithField("drySHA", drySHA) + } + if err != nil { + logCtx.WithField("appCount", len(relevantApps)).WithError(err).Error("Failed to hydrate apps") + for _, app := range relevantApps { + origApp := app.DeepCopy() + app.Status.SourceHydrator.CurrentOperation.Phase = appv1.HydrateOperationPhaseFailed + failedAt := metav1.Now() + app.Status.SourceHydrator.CurrentOperation.FinishedAt = &failedAt + app.Status.SourceHydrator.CurrentOperation.Message = fmt.Sprintf("Failed to hydrated revision %s: %v", drySHA, err.Error()) + h.dependencies.PersistAppHydratorStatus(origApp, &app.Status.SourceHydrator) + logCtx = logCtx.WithField("app", app.QualifiedName()) + logCtx.Errorf("Failed to hydrate app: %v", err) + } + return + } + logCtx.WithField("appCount", len(relevantApps)).Debug("Successfully hydrated apps") + finishedAt := metav1.Now() + for _, app := range relevantApps { + origApp := app.DeepCopy() + operation := &appv1.HydrateOperation{ + StartedAt: app.Status.SourceHydrator.CurrentOperation.StartedAt, + FinishedAt: &finishedAt, + Phase: appv1.HydrateOperationPhaseHydrated, + Message: "", + DrySHA: drySHA, + HydratedSHA: hydratedSHA, + SourceHydrator: app.Status.SourceHydrator.CurrentOperation.SourceHydrator, + } + app.Status.SourceHydrator.CurrentOperation = operation + app.Status.SourceHydrator.LastSuccessfulOperation = &appv1.SuccessfulHydrateOperation{ + DrySHA: drySHA, + HydratedSHA: hydratedSHA, + SourceHydrator: app.Status.SourceHydrator.CurrentOperation.SourceHydrator, + } + h.dependencies.PersistAppHydratorStatus(origApp, &app.Status.SourceHydrator) + // Request a refresh since we pushed a new commit. + h.dependencies.RequestAppRefresh(app.QualifiedName()) + } + return +} + +func (h *Hydrator) hydrateAppsLatestCommit(logCtx *log.Entry, hydrationKey HydrationQueueKey) ([]*appv1.Application, string, string, error) { + relevantApps, err := h.getRelevantAppsForHydration(logCtx, hydrationKey) + if err != nil { + return nil, "", "", fmt.Errorf("failed to get relevant apps for hydration: %w", err) + } + + hydratedRevision, dryRevision, err := h.hydrate(logCtx, relevantApps) + if err != nil { + return relevantApps, dryRevision, "", fmt.Errorf("failed to hydrate apps: %w", err) + } + + return relevantApps, dryRevision, hydratedRevision, nil +} + +func (h *Hydrator) getRelevantAppsForHydration(logCtx *log.Entry, hydrationKey HydrationQueueKey) ([]*appv1.Application, error) { + // Get all apps + apps, err := h.dependencies.GetProcessableApps() + if err != nil { + return nil, fmt.Errorf("failed to list apps: %w", err) + } + + var relevantApps []*appv1.Application + uniqueDestinations := make(map[uniqueHydrationDestination]bool, len(apps.Items)) + for _, app := range apps.Items { + if app.Spec.SourceHydrator == nil { + continue + } + + if app.Spec.SourceHydrator.DrySource.RepoURL != hydrationKey.SourceRepoURL || + app.Spec.SourceHydrator.DrySource.TargetRevision != hydrationKey.SourceTargetRevision { + continue + } + destinationBranch := app.Spec.SourceHydrator.SyncSource.TargetBranch + if app.Spec.SourceHydrator.HydrateTo != nil { + destinationBranch = app.Spec.SourceHydrator.HydrateTo.TargetBranch + } + if destinationBranch != hydrationKey.DestinationBranch { + continue + } + + var proj *appv1.AppProject + proj, err = h.dependencies.GetProcessableAppProj(&app) + if err != nil { + return nil, fmt.Errorf("failed to get project %q for app %q: %w", app.Spec.Project, app.QualifiedName(), err) + } + permitted := proj.IsSourcePermitted(app.Spec.GetSource()) + if !permitted { + // Log and skip. We don't want to fail the entire operation because of one app. + logCtx.Warnf("App %q is not permitted to use source %q", app.QualifiedName(), app.Spec.Source.String()) + continue + } + + uniqueDestinationKey := uniqueHydrationDestination{ + sourceRepoURL: app.Spec.SourceHydrator.DrySource.RepoURL, + sourceTargetRevision: app.Spec.SourceHydrator.DrySource.TargetRevision, + destinationBranch: destinationBranch, + destinationPath: app.Spec.SourceHydrator.SyncSource.Path, + } + // TODO: test the dupe detection + if _, ok := uniqueDestinations[uniqueDestinationKey]; ok { + return nil, fmt.Errorf("multiple app hydrators use the same destination: %v", uniqueDestinationKey) + } + uniqueDestinations[uniqueDestinationKey] = true + + relevantApps = append(relevantApps, &app) + } + return relevantApps, nil +} + +func (h *Hydrator) hydrate(logCtx *log.Entry, apps []*appv1.Application) (string, string, error) { + if len(apps) == 0 { + return "", "", nil + } + repoURL := apps[0].Spec.SourceHydrator.DrySource.RepoURL + syncBranch := apps[0].Spec.SourceHydrator.SyncSource.TargetBranch + targetBranch := apps[0].Spec.GetHydrateToSource().TargetRevision + var paths []*commitclient.PathDetails + projects := make(map[string]bool, len(apps)) + var targetRevision string + // TODO: parallelize this loop + for _, app := range apps { + project, err := h.dependencies.GetProcessableAppProj(app) + if err != nil { + return "", "", fmt.Errorf("failed to get project: %w", err) + } + projects[project.Name] = true + drySource := appv1.ApplicationSource{ + RepoURL: app.Spec.SourceHydrator.DrySource.RepoURL, + Path: app.Spec.SourceHydrator.DrySource.Path, + TargetRevision: app.Spec.SourceHydrator.DrySource.TargetRevision, + } + if targetRevision == "" { + targetRevision = app.Spec.SourceHydrator.DrySource.TargetRevision + } + + // TODO: enable signature verification + objs, resp, err := h.dependencies.GetRepoObjs(app, drySource, targetRevision, project) + if err != nil { + return "", "", fmt.Errorf("failed to get repo objects: %w", err) + } + + targetRevision = resp.Revision + + // Set up a ManifestsRequest + manifestDetails := make([]*commitclient.HydratedManifestDetails, len(objs)) + for i, obj := range objs { + objJson, err := json.Marshal(obj) + if err != nil { + return "", "", fmt.Errorf("failed to marshal object: %w", err) + } + manifestDetails[i] = &commitclient.HydratedManifestDetails{ManifestJSON: string(objJson)} + } + + paths = append(paths, &commitclient.PathDetails{ + Path: app.Spec.SourceHydrator.SyncSource.Path, + Manifests: manifestDetails, + Commands: resp.Commands, + }) + } + + // If all the apps are under the same project, use that project. Otherwise, use an empty string to indicate that we + // need global creds. + project := "" + if len(projects) == 1 { + for p := range projects { + project = p + } + } + + repo, err := h.dependencies.GetWriteCredentials(context.Background(), repoURL, project) + if err != nil { + return "", "", fmt.Errorf("failed to get hydrator credentials: %w", err) + } + if repo == nil { + // Try without credentials. + repo = &appv1.Repository{ + Repo: repoURL, + } + logCtx.Warn("no credentials found for repo, continuing without credentials") + } + + manifestsRequest := commitclient.CommitHydratedManifestsRequest{ + Repo: repo, + SyncBranch: syncBranch, + TargetBranch: targetBranch, + DrySha: targetRevision, + CommitMessage: fmt.Sprintf("[Argo CD Bot] hydrate %s", targetRevision), + Paths: paths, + } + + closer, commitService, err := h.commitClientset.NewCommitServerClient() + if err != nil { + return "", "", fmt.Errorf("failed to create commit service: %w", err) + } + defer argoio.Close(closer) + resp, err := commitService.CommitHydratedManifests(context.Background(), &manifestsRequest) + if err != nil { + return "", "", fmt.Errorf("failed to commit hydrated manifests: %w", err) + } + return targetRevision, resp.HydratedSha, nil +} + +// appNeedsHydration answers if application needs manifests hydrated. +func appNeedsHydration(app *appv1.Application, statusHydrateTimeout time.Duration) (needsHydration bool, reason string) { + if app.Spec.SourceHydrator == nil { + return false, "source hydrator not configured" + } + + var hydratedAt *metav1.Time + if app.Status.SourceHydrator.CurrentOperation != nil { + hydratedAt = &app.Status.SourceHydrator.CurrentOperation.StartedAt + } + + if app.IsHydrateRequested() { + return true, "hydrate requested" + } else if app.Status.SourceHydrator.CurrentOperation == nil { + return true, "no previous hydrate operation" + } else if !app.Spec.SourceHydrator.DeepEquals(app.Status.SourceHydrator.CurrentOperation.SourceHydrator) { + return true, "spec.sourceHydrator differs" + } else if app.Status.SourceHydrator.CurrentOperation.Phase == appv1.HydrateOperationPhaseFailed && metav1.Now().Sub(app.Status.SourceHydrator.CurrentOperation.FinishedAt.Time) > 2*time.Minute { + return true, "previous hydrate operation failed more than 2 minutes ago" + } else if hydratedAt == nil || hydratedAt.Add(statusHydrateTimeout).Before(time.Now().UTC()) { + return true, "hydration expired" + } + + return false, "" +} diff --git a/controller/hydrator/hydrator_test.go b/controller/hydrator/hydrator_test.go new file mode 100644 index 0000000000000..c4e62931a5348 --- /dev/null +++ b/controller/hydrator/hydrator_test.go @@ -0,0 +1,103 @@ +package hydrator + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func Test_appNeedsHydration(t *testing.T) { + t.Parallel() + + now := metav1.NewTime(time.Now()) + oneHourAgo := metav1.NewTime(now.Add(-1 * time.Hour)) + + testCases := []struct { + name string + app *v1alpha1.Application + timeout time.Duration + expectedNeedsHydration bool + expectedMessage string + }{ + { + name: "source hydrator not configured", + app: &v1alpha1.Application{}, + expectedNeedsHydration: false, + expectedMessage: "source hydrator not configured", + }, + { + name: "hydrate requested", + app: &v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{v1alpha1.AnnotationKeyHydrate: "normal"}}, + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + }, + timeout: 1 * time.Hour, + expectedNeedsHydration: true, + expectedMessage: "hydrate requested", + }, + { + name: "no previous hydrate operation", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + }, + timeout: 1 * time.Hour, + expectedNeedsHydration: true, + expectedMessage: "no previous hydrate operation", + }, + { + name: "spec.sourceHydrator differs", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + Status: v1alpha1.ApplicationStatus{SourceHydrator: v1alpha1.SourceHydratorStatus{CurrentOperation: &v1alpha1.HydrateOperation{ + SourceHydrator: v1alpha1.SourceHydrator{DrySource: v1alpha1.DrySource{RepoURL: "something new"}}, + }}}, + }, + timeout: 1 * time.Hour, + expectedNeedsHydration: true, + expectedMessage: "spec.sourceHydrator differs", + }, + { + name: "hydration failed more than two minutes ago", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + Status: v1alpha1.ApplicationStatus{SourceHydrator: v1alpha1.SourceHydratorStatus{CurrentOperation: &v1alpha1.HydrateOperation{DrySHA: "abc123", FinishedAt: &oneHourAgo, Phase: v1alpha1.HydrateOperationPhaseFailed}}}, + }, + timeout: 1 * time.Hour, + expectedNeedsHydration: true, + expectedMessage: "previous hydrate operation failed more than 2 minutes ago", + }, + { + name: "timeout reached", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + Status: v1alpha1.ApplicationStatus{SourceHydrator: v1alpha1.SourceHydratorStatus{CurrentOperation: &v1alpha1.HydrateOperation{StartedAt: oneHourAgo}}}, + }, + timeout: 1 * time.Minute, + expectedNeedsHydration: true, + expectedMessage: "hydration expired", + }, + { + name: "hydrate not needed", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{SourceHydrator: &v1alpha1.SourceHydrator{}}, + Status: v1alpha1.ApplicationStatus{SourceHydrator: v1alpha1.SourceHydratorStatus{CurrentOperation: &v1alpha1.HydrateOperation{DrySHA: "abc123", StartedAt: now, FinishedAt: &now, Phase: v1alpha1.HydrateOperationPhaseFailed}}}, + }, + timeout: 1 * time.Hour, + expectedNeedsHydration: false, + expectedMessage: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + needsHydration, message := appNeedsHydration(tc.app, tc.timeout) + assert.Equal(t, tc.expectedNeedsHydration, needsHydration) + assert.Equal(t, tc.expectedMessage, message) + }) + } +} diff --git a/controller/hydrator_dependencies.go b/controller/hydrator_dependencies.go new file mode 100644 index 0000000000000..b9c0430a4206c --- /dev/null +++ b/controller/hydrator_dependencies.go @@ -0,0 +1,71 @@ +package controller + +import ( + "context" + "fmt" + + "github.com/argoproj/argo-cd/v2/controller/hydrator" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +/** +This file implements the hydrator.Dependencies interface for the ApplicationController. + +Hydration logic does not belong in this file. The methods here should be "bookkeeping" methods that keep hydration work +in the hydrator and app controller work in the app controller. The only purpose of this file is to provide the hydrator +safe, minimal access to certain app controller functionality to avoid duplicate code. +*/ + +func (ctrl *ApplicationController) GetProcessableAppProj(app *appv1.Application) (*appv1.AppProject, error) { + return ctrl.getAppProj(app) +} + +// GetProcessableApps returns a list of applications that are processable by the controller. +func (ctrl *ApplicationController) GetProcessableApps() (*appv1.ApplicationList, error) { + // getAppList already filters out applications that are not processable by the controller. + return ctrl.getAppList(metav1.ListOptions{}) +} + +func (ctrl *ApplicationController) GetRepoObjs(app *appv1.Application, source appv1.ApplicationSource, revision string, project *appv1.AppProject) ([]*unstructured.Unstructured, *apiclient.ManifestResponse, error) { + sources := []appv1.ApplicationSource{source} + revisions := []string{revision} + + appLabelKey, err := ctrl.settingsMgr.GetAppInstanceLabelKey() + if err != nil { + return nil, nil, fmt.Errorf("failed to get app instance label key: %w", err) + } + + // FIXME: use cache and revision cache + objs, resp, _, err := ctrl.appStateManager.GetRepoObjs(app, sources, appLabelKey, revisions, true, true, false, project, false, false) + if err != nil { + return nil, nil, fmt.Errorf("failed to get repo objects: %w", err) + } + + if len(resp) != 1 { + return nil, nil, fmt.Errorf("expected one manifest response, got %d", len(resp)) + } + + return objs, resp[0], nil +} + +func (ctrl *ApplicationController) GetWriteCredentials(ctx context.Context, repoURL string, project string) (*appv1.Repository, error) { + return ctrl.db.GetWriteRepository(ctx, repoURL, project) +} + +func (ctrl *ApplicationController) RequestAppRefresh(appName string) { + ctrl.requestAppRefresh(appName, CompareWithLatest.Pointer(), nil) +} + +func (ctrl *ApplicationController) PersistAppHydratorStatus(orig *appv1.Application, newStatus *appv1.SourceHydratorStatus) { + status := orig.Status.DeepCopy() + status.SourceHydrator = *newStatus + ctrl.persistAppStatus(orig, status) +} + +func (ctrl *ApplicationController) AddHydrationQueueItem(key hydrator.HydrationQueueKey) { + ctrl.hydrationQueue.AddRateLimited(key) +} diff --git a/controller/metrics/metrics.go b/controller/metrics/metrics.go index a9df75aff8015..70339499e0a13 100644 --- a/controller/metrics/metrics.go +++ b/controller/metrics/metrics.go @@ -30,17 +30,20 @@ import ( type MetricsServer struct { *http.Server - syncCounter *prometheus.CounterVec - kubectlExecCounter *prometheus.CounterVec - kubectlExecPendingGauge *prometheus.GaugeVec - k8sRequestCounter *prometheus.CounterVec - clusterEventsCounter *prometheus.CounterVec - redisRequestCounter *prometheus.CounterVec - reconcileHistogram *prometheus.HistogramVec - redisRequestHistogram *prometheus.HistogramVec - registry *prometheus.Registry - hostname string - cron *cron.Cron + syncCounter *prometheus.CounterVec + kubectlExecCounter *prometheus.CounterVec + kubectlExecPendingGauge *prometheus.GaugeVec + orphanedResourcesGauge *prometheus.GaugeVec + k8sRequestCounter *prometheus.CounterVec + clusterEventsCounter *prometheus.CounterVec + redisRequestCounter *prometheus.CounterVec + reconcileHistogram *prometheus.HistogramVec + redisRequestHistogram *prometheus.HistogramVec + resourceEventsProcessingHistogram *prometheus.HistogramVec + resourceEventsNumberGauge *prometheus.GaugeVec + registry *prometheus.Registry + hostname string + cron *cron.Cron } const ( @@ -144,6 +147,28 @@ var ( }, []string{"hostname", "initiator"}, ) + + orphanedResourcesGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "argocd_app_orphaned_resources_count", + Help: "Number of orphaned resources per application", + }, + descAppDefaultLabels, + ) + + resourceEventsProcessingHistogram = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_resource_events_processing", + Help: "Time to process resource events in seconds.", + Buckets: []float64{0.25, .5, 1, 2, 4, 8, 16}, + }, + []string{"server"}, + ) + + resourceEventsNumberGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "argocd_resource_events_processed_in_batch", + Help: "Number of resource events processed in batch", + }, []string{"server"}) ) // NewMetricsServer returns a new prometheus server which collects application metrics @@ -188,10 +213,13 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil registry.MustRegister(k8sRequestCounter) registry.MustRegister(kubectlExecCounter) registry.MustRegister(kubectlExecPendingGauge) + registry.MustRegister(orphanedResourcesGauge) registry.MustRegister(reconcileHistogram) registry.MustRegister(clusterEventsCounter) registry.MustRegister(redisRequestCounter) registry.MustRegister(redisRequestHistogram) + registry.MustRegister(resourceEventsProcessingHistogram) + registry.MustRegister(resourceEventsNumberGauge) return &MetricsServer{ registry: registry, @@ -199,15 +227,18 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil Addr: addr, Handler: mux, }, - syncCounter: syncCounter, - k8sRequestCounter: k8sRequestCounter, - kubectlExecCounter: kubectlExecCounter, - kubectlExecPendingGauge: kubectlExecPendingGauge, - reconcileHistogram: reconcileHistogram, - clusterEventsCounter: clusterEventsCounter, - redisRequestCounter: redisRequestCounter, - redisRequestHistogram: redisRequestHistogram, - hostname: hostname, + syncCounter: syncCounter, + k8sRequestCounter: k8sRequestCounter, + kubectlExecCounter: kubectlExecCounter, + kubectlExecPendingGauge: kubectlExecPendingGauge, + orphanedResourcesGauge: orphanedResourcesGauge, + reconcileHistogram: reconcileHistogram, + clusterEventsCounter: clusterEventsCounter, + redisRequestCounter: redisRequestCounter, + redisRequestHistogram: redisRequestHistogram, + resourceEventsProcessingHistogram: resourceEventsProcessingHistogram, + resourceEventsNumberGauge: resourceEventsNumberGauge, + hostname: hostname, // This cron is used to expire the metrics cache. // Currently clearing the metrics cache is logging and deleting from the map // so there is no possibility of panic, but we will add a chain to keep robfig/cron v1 behavior. @@ -241,6 +272,10 @@ func (m *MetricsServer) DecKubectlExecPending(command string) { m.kubectlExecPendingGauge.WithLabelValues(m.hostname, command).Dec() } +func (m *MetricsServer) SetOrphanedResourcesMetric(app *argoappv1.Application, numOrphanedResources int) { + m.orphanedResourcesGauge.WithLabelValues(app.Namespace, app.Name, app.Spec.GetProject()).Set(float64(numOrphanedResources)) +} + // IncClusterEventsCount increments the number of cluster events func (m *MetricsServer) IncClusterEventsCount(server, group, kind string) { m.clusterEventsCounter.WithLabelValues(server, group, kind).Inc() @@ -269,6 +304,12 @@ func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) { m.redisRequestHistogram.WithLabelValues(m.hostname, common.ApplicationController).Observe(duration.Seconds()) } +// ObserveResourceEventsProcessingDuration observes resource events processing duration +func (m *MetricsServer) ObserveResourceEventsProcessingDuration(server string, duration time.Duration, processedEventsNumber int) { + m.resourceEventsProcessingHistogram.WithLabelValues(server).Observe(duration.Seconds()) + m.resourceEventsNumberGauge.WithLabelValues(server).Set(float64(processedEventsNumber)) +} + // IncReconcile increments the reconcile counter for an application func (m *MetricsServer) IncReconcile(app *argoappv1.Application, duration time.Duration) { m.reconcileHistogram.WithLabelValues(app.Namespace, app.Spec.Destination.Server).Observe(duration.Seconds()) @@ -290,11 +331,14 @@ func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error { m.syncCounter.Reset() m.kubectlExecCounter.Reset() m.kubectlExecPendingGauge.Reset() + m.orphanedResourcesGauge.Reset() m.k8sRequestCounter.Reset() m.clusterEventsCounter.Reset() m.redisRequestCounter.Reset() m.reconcileHistogram.Reset() m.redisRequestHistogram.Reset() + m.resourceEventsProcessingHistogram.Reset() + m.resourceEventsNumberGauge.Reset() }) if err != nil { return err diff --git a/controller/metrics/metrics_test.go b/controller/metrics/metrics_test.go index 44a6524ed7d85..383cb0c0c3d5a 100644 --- a/controller/metrics/metrics_test.go +++ b/controller/metrics/metrics_test.go @@ -467,6 +467,7 @@ func assertMetricsPrinted(t *testing.T, expectedLines, body string) { // assertMetricsNotPrinted func assertMetricsNotPrinted(t *testing.T, expectedLines, body string) { + t.Helper() for _, line := range strings.Split(expectedLines, "\n") { if line == "" { continue @@ -508,6 +509,31 @@ argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argoc assertMetricsPrinted(t, appReconcileMetrics, body) } +func TestOrphanedResourcesMetric(t *testing.T) { + cancel, appLister := newFakeLister() + defer cancel() + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) + + expectedMetrics := ` +# HELP argocd_app_orphaned_resources_count Number of orphaned resources per application +# TYPE argocd_app_orphaned_resources_count gauge +argocd_app_orphaned_resources_count{name="my-app-4",namespace="argocd",project="important-project"} 1 +` + app := newFakeApp(fakeApp4) + numOrphanedResources := 1 + metricsServ.SetOrphanedResourcesMetric(app, numOrphanedResources) + + req, err := http.NewRequest(http.MethodGet, "/metrics", nil) + require.NoError(t, err) + rr := httptest.NewRecorder() + metricsServ.Handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusOK, rr.Code) + body := rr.Body.String() + log.Println(body) + assertMetricsPrinted(t, expectedMetrics, body) +} + func TestMetricsReset(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() diff --git a/controller/sharding/sharding_test.go b/controller/sharding/sharding_test.go index ebd212062b199..b76741be92e16 100644 --- a/controller/sharding/sharding_test.go +++ b/controller/sharding/sharding_test.go @@ -226,7 +226,7 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunctionWhenClusterNumber // The other implementation was giving almost linear time of 400ms up to 10'000 clusters clusterPointers := []*v1alpha1.Cluster{} for i := 0; i < 2048; i++ { - cluster := createCluster(fmt.Sprintf("cluster-%d", i), fmt.Sprintf("%d", i)) + cluster := createCluster(fmt.Sprintf("cluster-%d", i), strconv.Itoa(i)) clusterPointers = append(clusterPointers, &cluster) } replicasCount := 2 @@ -836,6 +836,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Default sharding with statefulset", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerReplicas, "1") }, cleanup: func() {}, @@ -847,6 +848,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Default sharding with deployment", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvAppControllerName, common.DefaultApplicationControllerName) }, cleanup: func() {}, @@ -858,6 +860,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Default sharding with deployment and multiple replicas", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvAppControllerName, "argocd-application-controller-multi-replicas") }, cleanup: func() {}, @@ -869,6 +872,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Statefulset multiple replicas", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerReplicas, "3") osHostnameFunction = func() (string, error) { return "example-shard-3", nil } }, @@ -883,6 +887,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Explicit shard with statefulset and 1 replica", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerReplicas, "1") t.Setenv(common.EnvControllerShard, "3") }, @@ -895,6 +900,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Explicit shard with statefulset and 2 replica - and to high shard", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerReplicas, "2") t.Setenv(common.EnvControllerShard, "3") }, @@ -907,6 +913,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Explicit shard with statefulset and 2 replica", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerReplicas, "2") t.Setenv(common.EnvControllerShard, "1") }, @@ -919,6 +926,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Explicit shard with deployment", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvControllerShard, "3") }, cleanup: func() {}, @@ -930,6 +938,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Explicit shard with deployment and multiple replicas will read from configmap", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvAppControllerName, "argocd-application-controller-multi-replicas") t.Setenv(common.EnvControllerShard, "3") }, @@ -942,6 +951,7 @@ func TestGetClusterSharding(t *testing.T) { { name: "Dynamic sharding but missing deployment", envsSetter: func(t *testing.T) { + t.Helper() t.Setenv(common.EnvAppControllerName, "missing-deployment") }, cleanup: func() {}, diff --git a/controller/sharding/shuffle_test.go b/controller/sharding/shuffle_test.go index 4c05a8c7aeebd..390b82254555e 100644 --- a/controller/sharding/shuffle_test.go +++ b/controller/sharding/shuffle_test.go @@ -20,7 +20,7 @@ func TestLargeShuffle(t *testing.T) { clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{}} for i := 0; i < math.MaxInt/4096; i += 256 { // fmt.Fprintf(os.Stdout, "%d", i) - cluster := createCluster(fmt.Sprintf("cluster-%d", i), fmt.Sprintf("%d", i)) + cluster := createCluster(fmt.Sprintf("cluster-%d", i), strconv.Itoa(i)) clusterList.Items = append(clusterList.Items, cluster) } db.On("ListClusters", mock.Anything).Return(clusterList, nil) diff --git a/controller/state.go b/controller/state.go index bcac67961781c..a120158b802bf 100644 --- a/controller/state.go +++ b/controller/state.go @@ -10,6 +10,7 @@ import ( goSync "sync" "time" + synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" v1 "k8s.io/api/core/v1" "github.com/argoproj/gitops-engine/pkg/diff" @@ -70,7 +71,7 @@ type managedResource struct { type AppStateManager interface { CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool, rollback bool) (*comparisonResult, error) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) - GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) + GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback, sendRuntimeState bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) } // comparisonResult holds the state of an application after the reconciliation @@ -124,7 +125,7 @@ type appStateManager struct { // task to the repo-server. It returns the list of generated manifests as unstructured // objects. It also returns the full response from all calls to the repo server as the // second argument. -func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) { +func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback, sendRuntimeState bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) { ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) if err != nil { @@ -161,6 +162,11 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp return nil, nil, false, fmt.Errorf("failed to get Helm settings: %w", err) } + installationID, err := m.settingsMgr.GetInstallationID() + if err != nil { + return nil, nil, false, fmt.Errorf("failed to get installation ID: %w", err) + } + ts.AddCheckpoint("build_options_ms") serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server) if err != nil { @@ -213,6 +219,14 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp revision := revisions[i] + appNamespace := app.Spec.Destination.Namespace + apiVersions := argo.APIResourcesToStrings(apiResources, true) + if !sendRuntimeState { + appNamespace = "" + apiVersions = nil + serverVersion = "" + } + if !source.IsHelm() && syncedRevision != "" && keyManifestGenerateAnnotationExists && keyManifestGenerateAnnotationVal != "" { // Validate the manifest-generate-path annotation to avoid generating manifests if it has not changed. updateRevisionResult, err := repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{ @@ -223,13 +237,14 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp Paths: path.GetAppRefreshPaths(app), AppLabelKey: appLabelKey, AppName: app.InstanceName(m.namespace), - Namespace: app.Spec.Destination.Namespace, + Namespace: appNamespace, ApplicationSource: &source, KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), + ApiVersions: apiVersions, TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), RefSources: refSources, HasMultipleSources: app.Spec.HasMultipleSources(), + InstallationID: installationID, }) if err != nil { return nil, nil, false, fmt.Errorf("failed to compare revisions for source %d of %d: %w", i+1, len(sources), err) @@ -249,27 +264,29 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp log.Debugf("Generating Manifest for source %s revision %s", source, revision) manifestInfo, err := repoClient.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: repo, - Repos: permittedHelmRepos, - Revision: revision, - NoCache: noCache, - NoRevisionCache: noRevisionCache, - AppLabelKey: appLabelKey, - AppName: app.InstanceName(m.namespace), - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - VerifySignature: verifySignature, - HelmRepoCreds: permittedHelmCredentials, - TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), - EnabledSourceTypes: enabledSourceTypes, - HelmOptions: helmOptions, - HasMultipleSources: app.Spec.HasMultipleSources(), - RefSources: refSources, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: repo, + Repos: permittedHelmRepos, + Revision: revision, + NoCache: noCache, + NoRevisionCache: noRevisionCache, + AppLabelKey: appLabelKey, + AppName: app.InstanceName(m.namespace), + Namespace: appNamespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: apiVersions, + VerifySignature: verifySignature, + HelmRepoCreds: permittedHelmCredentials, + TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), + EnabledSourceTypes: enabledSourceTypes, + HelmOptions: helmOptions, + HasMultipleSources: app.Spec.HasMultipleSources(), + RefSources: refSources, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: app.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), + InstallationID: installationID, }) if err != nil { return nil, nil, false, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err) @@ -291,7 +308,8 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Info("GetRepoObjs stats") - // in case if annotation not exists, we should always execute selfheal if manifests changed + // If a revision in any of the sources cannot be updated, + // we should trigger self-healing whenever there are changes to the manifests. if atLeastOneRevisionIsNotPossibleToBeUpdated { revisionUpdated = true } @@ -299,6 +317,39 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp return targetObjs, manifestInfos, revisionUpdated, nil } +// ResolveGitRevision will resolve the given revision to a full commit SHA. Only works for git. +func (m *appStateManager) ResolveGitRevision(repoURL string, revision string) (string, error) { + conn, repoClient, err := m.repoClientset.NewRepoServerClient() + if err != nil { + return "", fmt.Errorf("failed to connect to repo server: %w", err) + } + defer io.Close(conn) + + repo, err := m.db.GetRepository(context.Background(), repoURL, "") + if err != nil { + return "", fmt.Errorf("failed to get repo %q: %w", repoURL, err) + } + + // Mock the app. The repo-server only needs to know whether the "chart" field is populated. + app := &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: repoURL, + TargetRevision: revision, + }, + }, + } + resp, err := repoClient.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ + Repo: repo, + App: app, + AmbiguousRevision: revision, + }) + if err != nil { + return "", fmt.Errorf("failed to determine whether the dry source has changed: %w", err) + } + return resp.Revision, nil +} + func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) { targetObjs := make([]*unstructured.Unstructured, 0) for _, manifest := range manifests { @@ -353,20 +404,24 @@ func DeduplicateTargetObjects( // getComparisonSettings will return the system level settings related to the // diff/normalization process. -func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, error) { +func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, error) { resourceOverrides, err := m.settingsMgr.GetResourceOverrides() if err != nil { - return "", nil, nil, err + return "", nil, nil, "", err } appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey() if err != nil { - return "", nil, nil, err + return "", nil, nil, "", err } resFilter, err := m.settingsMgr.GetResourcesFilter() if err != nil { - return "", nil, nil, err + return "", nil, nil, "", err + } + installationID, err := m.settingsMgr.GetInstallationID() + if err != nil { + return "", nil, nil, "", err } - return appLabelKey, resourceOverrides, resFilter, nil + return appLabelKey, resourceOverrides, resFilter, installationID, nil } // verifyGnuPGSignature verifies the result of a GnuPG operation for a given git @@ -417,29 +472,30 @@ func isManagedNamespace(ns *unstructured.Unstructured, app *v1alpha1.Application // revision and overrides in the app spec. func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool, rollback bool) (*comparisonResult, error) { ts := stats.NewTimingStats() - appLabelKey, resourceOverrides, resFilter, err := m.getComparisonSettings() + appLabelKey, resourceOverrides, resFilter, installationID, err := m.getComparisonSettings() ts.AddCheckpoint("settings_ms") // return unknown comparison result if basic comparison settings cannot be loaded if err != nil { + now := metav1.Now() if hasMultipleSources { return &comparisonResult{ syncStatus: &v1alpha1.SyncStatus{ - ComparedTo: v1alpha1.ComparedTo{Destination: app.Spec.Destination, Sources: sources, IgnoreDifferences: app.Spec.IgnoreDifferences}, + ComparedTo: app.Spec.BuildComparedToStatus(), Status: v1alpha1.SyncStatusCodeUnknown, Revisions: revisions, }, - healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, + healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now}, }, nil } else { return &comparisonResult{ syncStatus: &v1alpha1.SyncStatus{ - ComparedTo: v1alpha1.ComparedTo{Source: sources[0], Destination: app.Spec.Destination, IgnoreDifferences: app.Spec.IgnoreDifferences}, + ComparedTo: app.Spec.BuildComparedToStatus(), Status: v1alpha1.SyncStatusCodeUnknown, Revision: revisions[0], }, - healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, + healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now}, }, nil } } @@ -475,7 +531,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } - targetObjs, manifestInfos, revisionUpdated, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project, rollback) + targetObjs, manifestInfos, revisionUpdated, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project, rollback, true) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) msg := fmt.Sprintf("Failed to load target state: %s", err.Error()) @@ -585,7 +641,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 for _, liveObj := range liveObjByKey { if liveObj != nil { - appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod) + appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod, installationID) if appInstanceName != "" && appInstanceName != app.InstanceName(m.namespace) { fqInstanceName := strings.ReplaceAll(appInstanceName, "_", "/") conditions = append(conditions, v1alpha1.ApplicationCondition{ @@ -724,7 +780,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } gvk := obj.GroupVersionKind() - isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), appLabelKey, trackingMethod) + isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), appLabelKey, trackingMethod, installationID) resState := v1alpha1.ResourceStatus{ Namespace: obj.GetNamespace(), @@ -734,6 +790,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 Group: gvk.Group, Hook: isHook(obj), RequiresPruning: targetObj == nil && liveObj != nil && isSelfReferencedObj, + RequiresDeletionConfirmation: targetObj != nil && resourceutil.HasAnnotationOption(targetObj, synccommon.AnnotationSyncOptions, synccommon.SyncOptionDeleteRequireConfirm) || + liveObj != nil && resourceutil.HasAnnotationOption(liveObj, synccommon.AnnotationSyncOptions, synccommon.SyncOptionDeleteRequireConfirm), } if targetObj != nil { resState.SyncWave = int64(syncwaves.Wave(targetObj)) @@ -924,9 +982,7 @@ func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sou return false } - currentSpec := app.BuildComparedToStatus() - specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, currentSpec) - if specChanged { + if !specEqualsCompareTo(app.Spec, app.Status.Sync.ComparedTo) { log.WithField("useDiffCache", "false").Debug("specChanged") return false } @@ -935,6 +991,29 @@ func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sou return true } +// specEqualsCompareTo compares the application spec to the comparedTo status. It normalizes the destination to match +// the comparedTo destination before comparing. It does not mutate the original spec or comparedTo. +func specEqualsCompareTo(spec v1alpha1.ApplicationSpec, comparedTo v1alpha1.ComparedTo) bool { + // Make a copy to be sure we don't mutate the original. + specCopy := spec.DeepCopy() + currentSpec := specCopy.BuildComparedToStatus() + + // The spec might have been augmented to include both server and name, so change it to match the comparedTo before + // comparing. + if comparedTo.Destination.Server == "" { + currentSpec.Destination.Server = "" + } + if comparedTo.Destination.Name == "" { + currentSpec.Destination.Name = "" + } + + // Set IsServerInferred to false on both, because that field is not important for comparison. + comparedTo.Destination.SetIsServerInferred(false) + currentSpec.Destination.SetIsServerInferred(false) + + return reflect.DeepEqual(comparedTo, currentSpec) +} + func (m *appStateManager) persistRevisionHistory( app *v1alpha1.Application, revision string, @@ -1029,7 +1108,7 @@ func NewAppStateManager( // group and kind) match the properties of the live object, or if the tracking method // used does not provide the required properties for matching. // Reference: https://github.com/argoproj/argo-cd/issues/8683 -func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstructured, appName, appLabelKey string, trackingMethod v1alpha1.TrackingMethod) bool { +func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstructured, appName, appLabelKey string, trackingMethod v1alpha1.TrackingMethod, installationID string) bool { if live == nil { return true } @@ -1062,7 +1141,7 @@ func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstruc // to match the properties from the live object. Cluster scoped objects // carry the app's destination namespace in the tracking annotation, // but are unique in GVK + name combination. - appInstance := m.resourceTracking.GetAppInstance(live, appLabelKey, trackingMethod) + appInstance := m.resourceTracking.GetAppInstance(live, appLabelKey, trackingMethod, installationID) if appInstance != nil { return isSelfReferencedObj(live, *appInstance) } diff --git a/controller/state_test.go b/controller/state_test.go index a3b7cb195a94e..2efc51718f9ef 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -28,7 +28,6 @@ import ( "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" - mockrepoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" "github.com/argoproj/argo-cd/v2/test" "github.com/argoproj/argo-cd/v2/util/argo" ) @@ -548,6 +547,7 @@ func TestAppRevisionsMultiSource(t *testing.T) { } func toJSON(t *testing.T, obj *unstructured.Unstructured) string { + t.Helper() data, err := json.Marshal(obj) require.NoError(t, err) return string(data) @@ -680,7 +680,6 @@ func TestCompareAppStateWithManifestGeneratePath(t *testing.T) { assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, "abc123", compRes.syncStatus.Revision) - ctrl.repoClientset.(*mockrepoclient.Clientset).RepoServerServiceClient.(*mockrepoclient.RepoServerServiceClient).AssertNumberOfCalls(t, "UpdateRevisionForPaths", 1) } func TestSetHealth(t *testing.T) { @@ -716,6 +715,44 @@ func TestSetHealth(t *testing.T) { require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero()) +} + +func TestPreserveStatusTimestamp(t *testing.T) { + timestamp := metav1.Now() + app := newFakeAppWithHealthAndTime(health.HealthStatusHealthy, timestamp) + deployment := kube.MustToUnstructured(&v1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "demo", + Namespace: "default", + }, + }) + ctrl := newFakeController(&fakeData{ + apps: []runtime.Object{app, &defaultProj}, + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(deployment): deployment, + }, + }, nil) + + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) + require.NoError(t, err) + + assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.Equal(t, timestamp, *compRes.healthStatus.LastTransitionTime) } func TestSetHealthSelfReferencedApp(t *testing.T) { @@ -753,6 +790,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) + assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero()) } func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { @@ -828,6 +866,7 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { require.NoError(t, err) assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status) + assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero()) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) } @@ -1372,8 +1411,8 @@ func TestIsLiveResourceManaged(t *testing.T) { configObj := managedObj.DeepCopy() // then - assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) - assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) + assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) t.Run("will return true if tracked with label", func(t *testing.T) { // given @@ -1381,43 +1420,43 @@ func TestIsLiveResourceManaged(t *testing.T) { configObj := managedObjWithLabel.DeepCopy() // then - assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) + assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) }) t.Run("will handle if trackingId has wrong resource name and config is nil", func(t *testing.T) { // given t.Parallel() // then - assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) + assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) t.Run("will handle if trackingId has wrong resource group and config is nil", func(t *testing.T) { // given t.Parallel() // then - assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) + assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) t.Run("will handle if trackingId has wrong kind and config is nil", func(t *testing.T) { // given t.Parallel() // then - assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) + assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) t.Run("will handle if trackingId has wrong namespace and config is nil", func(t *testing.T) { // given t.Parallel() // then - assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel)) - assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel)) + assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodLabel, "")) + assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotationAndLabel, "")) }) t.Run("will return true if live is nil", func(t *testing.T) { t.Parallel() - assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) t.Run("will handle upgrade in desired state APIGroup", func(t *testing.T) { @@ -1427,11 +1466,13 @@ func TestIsLiveResourceManaged(t *testing.T) { delete(config.GetAnnotations(), common.AnnotationKeyAppInstance) // then - assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) + assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation, "")) }) } func TestUseDiffCache(t *testing.T) { + t.Parallel() + type fixture struct { testName string noCache bool @@ -1527,6 +1568,10 @@ func TestUseDiffCache(t *testing.T) { t.Fatalf("error merging app: %s", err) } } + if app.Spec.Destination.Name != "" && app.Spec.Destination.Server != "" { + // Simulate the controller's process for populating both of these fields. + app.Spec.Destination.SetInferredServer(app.Spec.Destination.Server) + } return app } @@ -1692,6 +1737,44 @@ func TestUseDiffCache(t *testing.T) { expectedUseCache: false, serverSideDiff: false, }, + { + // There are code paths that modify the ApplicationSpec and augment the destination field with both the + // destination server and name. Since both fields are populated in the app spec but not in the comparedTo, + // we need to make sure we correctly compare the fields and don't miss the cache. + testName: "will return true if the app spec destination contains both server and name, but otherwise matches comparedTo", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Name: "httpbin", + Namespace: "httpbin", + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + }, + Revision: "rev1", + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + serverSideDiff: true, + }, } for _, tc := range cases { diff --git a/controller/sync.go b/controller/sync.go index 5f896a522f942..dcbb768a79be8 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -44,6 +44,10 @@ const ( // EnvVarSyncWaveDelay is an environment variable which controls the delay in seconds between // each sync-wave EnvVarSyncWaveDelay = "ARGOCD_SYNC_WAVE_DELAY" + + // serviceAccountDisallowedCharSet contains the characters that are not allowed to be present + // in a DefaultServiceAccount configured for a DestinationServiceAccount + serviceAccountDisallowedCharSet = "!*[]{}\\/" ) func (m *appStateManager) getOpenAPISchema(server string) (openapi.Resources, error) { @@ -76,7 +80,12 @@ func (m *appStateManager) getResourceOperations(server string) (kube.ResourceOpe if err != nil { return nil, nil, fmt.Errorf("error getting cluster: %w", err) } - ops, cleanup, err := m.kubectl.ManageResources(cluster.RawRestConfig(), clusterCache.GetOpenAPISchema()) + + rawConfig, err := cluster.RawRestConfig() + if err != nil { + return nil, nil, fmt.Errorf("error getting cluster REST config: %w", err) + } + ops, cleanup, err := m.kubectl.ManageResources(rawConfig, clusterCache.GetOpenAPISchema()) if err != nil { return nil, nil, fmt.Errorf("error creating kubectl ResourceOperations: %w", err) } @@ -170,12 +179,18 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha state.Phase = common.OperationError state.Message = fmt.Sprintf("Failed to load application project: %v", err) return - } else if syncWindowPreventsSync(app, proj) { - // If the operation is currently running, simply let the user know the sync is blocked by a current sync window - if state.Phase == common.OperationRunning { - state.Message = "Sync operation blocked by sync window" + } else { + isBlocked, err := syncWindowPreventsSync(app, proj) + if isBlocked { + // If the operation is currently running, simply let the user know the sync is blocked by a current sync window + if state.Phase == common.OperationRunning { + state.Message = "Sync operation blocked by sync window" + if err != nil { + state.Message = fmt.Sprintf("%s: %v", state.Message, err) + } + } + return } - return } if !isMultiSourceRevision { @@ -213,8 +228,20 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha return } - rawConfig := clst.RawRestConfig() - restConfig := metrics.AddMetricsTransportWrapper(m.metricsServer, app, clst.RESTConfig()) + rawConfig, err := clst.RawRestConfig() + if err != nil { + state.Phase = common.OperationError + state.Message = err.Error() + return + } + + clusterRESTConfig, err := clst.RESTConfig() + if err != nil { + state.Phase = common.OperationError + state.Message = err.Error() + return + } + restConfig := metrics.AddMetricsTransportWrapper(m.metricsServer, app, clusterRESTConfig) resourceOverrides, err := m.settingsMgr.GetResourceOverrides() if err != nil { @@ -285,10 +312,20 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha log.Errorf("Could not get appInstanceLabelKey: %v", err) return } + installationID, err := m.settingsMgr.GetInstallationID() + if err != nil { + log.Errorf("Could not get installation ID: %v", err) + return + } trackingMethod := argo.GetTrackingMethod(m.settingsMgr) - if m.settingsMgr.IsImpersonationEnabled() { - serviceAccountToImpersonate, err := deriveServiceAccountName(proj, app) + impersonationEnabled, err := m.settingsMgr.IsImpersonationEnabled() + if err != nil { + log.Errorf("could not get impersonation feature flag: %v", err) + return + } + if impersonationEnabled { + serviceAccountToImpersonate, err := deriveServiceAccountToImpersonate(proj, app) if err != nil { state.Phase = common.OperationError state.Message = fmt.Sprintf("failed to find a matching service account to impersonate: %v", err) @@ -331,7 +368,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha return (len(syncOp.Resources) == 0 || isPostDeleteHook(target) || argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) && - m.isSelfReferencedObj(live, target, app.GetName(), appLabelKey, trackingMethod) + m.isSelfReferencedObj(live, target, app.GetName(), appLabelKey, trackingMethod, installationID) }), sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)), sync.WithSyncWaveHook(delayBetweenSyncWaves), @@ -341,6 +378,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha sync.WithReplace(syncOp.SyncOptions.HasOption(common.SyncOptionReplace)), sync.WithServerSideApply(syncOp.SyncOptions.HasOption(common.SyncOptionServerSideApply)), sync.WithServerSideApplyManager(cdcommon.ArgoCDSSAManager), + sync.WithPruneConfirmed(app.IsDeletionConfirmed(state.StartedAt.Time)), } if syncOp.SyncOptions.HasOption("CreateNamespace=true") { @@ -548,18 +586,23 @@ func delayBetweenSyncWaves(phase common.SyncPhase, wave int, finalWave bool) err return nil } -func syncWindowPreventsSync(app *v1alpha1.Application, proj *v1alpha1.AppProject) bool { +func syncWindowPreventsSync(app *v1alpha1.Application, proj *v1alpha1.AppProject) (bool, error) { window := proj.Spec.SyncWindows.Matches(app) isManual := false if app.Status.OperationState != nil { isManual = !app.Status.OperationState.Operation.InitiatedBy.Automated } - return !window.CanSync(isManual) + canSync, err := window.CanSync(isManual) + if err != nil { + // prevents sync because sync window has an error + return true, err + } + return !canSync, nil } -// deriveServiceAccountName determines the service account to be used for impersonation for the sync operation. +// deriveServiceAccountToImpersonate determines the service account to be used for impersonation for the sync operation. // The returned service account will be fully qualified including namespace and the service account name in the format system:serviceaccount:: -func deriveServiceAccountName(project *v1alpha1.AppProject, application *v1alpha1.Application) (string, error) { +func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application *v1alpha1.Application) (string, error) { // spec.Destination.Namespace is optional. If not specified, use the Application's // namespace serviceAccountNamespace := application.Spec.Destination.Namespace @@ -569,10 +612,18 @@ func deriveServiceAccountName(project *v1alpha1.AppProject, application *v1alpha // Loop through the destinationServiceAccounts and see if there is any destination that is a candidate. // if so, return the service account specified for that destination. for _, item := range project.Spec.DestinationServiceAccounts { - dstServerMatched := glob.Match(item.Server, application.Spec.Destination.Server) - dstNamespaceMatched := glob.Match(item.Namespace, application.Spec.Destination.Namespace) + dstServerMatched, err := glob.MatchWithError(item.Server, application.Spec.Destination.Server) + if err != nil { + return "", fmt.Errorf("invalid glob pattern for destination server: %w", err) + } + dstNamespaceMatched, err := glob.MatchWithError(item.Namespace, application.Spec.Destination.Namespace) + if err != nil { + return "", fmt.Errorf("invalid glob pattern for destination namespace: %w", err) + } if dstServerMatched && dstNamespaceMatched { - if strings.Contains(item.DefaultServiceAccount, ":") { + if strings.Trim(item.DefaultServiceAccount, " ") == "" || strings.ContainsAny(item.DefaultServiceAccount, serviceAccountDisallowedCharSet) { + return "", fmt.Errorf("default service account contains invalid chars '%s'", item.DefaultServiceAccount) + } else if strings.Contains(item.DefaultServiceAccount, ":") { // service account is specified along with its namespace. return fmt.Sprintf("system:serviceaccount:%s", item.DefaultServiceAccount), nil } else { diff --git a/controller/sync_test.go b/controller/sync_test.go index 1dbfa2ff9e1a5..5560ffc2ec971 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -2,6 +2,7 @@ package controller import ( "context" + "strconv" "testing" "github.com/argoproj/gitops-engine/pkg/sync" @@ -9,6 +10,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -54,7 +56,7 @@ func TestPersistRevisionHistory(t *testing.T) { updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) require.NoError(t, err) - assert.Len(t, updatedApp.Status.History, 1) + require.Len(t, updatedApp.Status.History, 1) assert.Equal(t, app.Spec.GetSource(), updatedApp.Status.History[0].Source) assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) } @@ -644,6 +646,771 @@ func TestNormalizeTargetResourcesWithList(t *testing.T) { }) } +func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) { + type fixture struct { + project *v1alpha1.AppProject + application *v1alpha1.Application + } + + setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture { + project := &v1alpha1.AppProject{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "argocd-ns", + Name: "testProj", + }, + Spec: v1alpha1.AppProjectSpec{ + DestinationServiceAccounts: destinationServiceAccounts, + }, + } + app := &v1alpha1.Application{ + ObjectMeta: v1.ObjectMeta{ + Namespace: applicationNamespace, + Name: "testApp", + }, + Spec: v1alpha1.ApplicationSpec{ + Project: "testProj", + Destination: v1alpha1.ApplicationDestination{ + Server: destinationServerURL, + Namespace: destinationNamespace, + }, + }, + } + return &fixture{ + project: project, + application: app, + } + } + + t.Run("empty destination service accounts", func(t *testing.T) { + // given an application referring a project with no destination service accounts + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{} + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "" + expectedErrMsg := "no matching service account found for destination server https://kubernetes.svc.local and namespace testns" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + assert.Equal(t, expectedSA, sa) + + // then, there should be an error saying no valid match was found + assert.EqualError(t, err, expectedErrMsg) + }) + + t.Run("exact match of destination namespace", func(t *testing.T) { + // given an application referring a project with exactly one destination service account that matches the application destination, + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should be no error and should use the right service account for impersonation + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("exact one match with multiple destination service accounts", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts having one exact match for application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "guestbook-test", + DefaultServiceAccount: "guestbook-test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should be no error and should use the right service account for impersonation + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("first match to be used when multiple matches are available", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts having multiple match for application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-3", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should be no error and it should use the first matching service account for impersonation + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("first match to be used when glob pattern is used", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with glob patterns matching the application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "test*", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and should use the first matching glob pattern service account for impersonation + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("no match among a valid list", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with no matches for application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "test1", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "test2", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "" + expectedErrMsg := "no matching service account found for destination server https://kubernetes.svc.local and namespace testns" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should be an error saying no match was found + require.EqualError(t, err, expectedErrMsg) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("app destination namespace is empty", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with empty application destination namespace + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "*", + DefaultServiceAccount: "test-sa-2", + }, + } + destinationNamespace := "" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:argocd-ns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and the service account configured for with empty namespace should be used. + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("match done via catch all glob pattern", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts having a catch all glob pattern + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns1", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "*", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and the catch all service account should be returned + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("match done via invalid glob pattern", func(t *testing.T) { + // given an application referring a project with a destination service account having an invalid glob pattern for namespace + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "e[[a*", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there must be an error as the glob pattern is invalid. + require.ErrorContains(t, err, "invalid glob pattern for destination namespace") + assert.Equal(t, expectedSA, sa) + }) + + t.Run("sa specified with a namespace", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts having a matching service account specified with its namespace + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "myns:test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "*", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:myns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + assert.Equal(t, expectedSA, sa) + + // then, there should not be any error and the service account with its namespace should be returned. + require.NoError(t, err) + }) +} + +func TestDeriveServiceAccountMatchingServers(t *testing.T) { + type fixture struct { + project *v1alpha1.AppProject + application *v1alpha1.Application + } + + setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture { + project := &v1alpha1.AppProject{ + ObjectMeta: v1.ObjectMeta{ + Namespace: "argocd-ns", + Name: "testProj", + }, + Spec: v1alpha1.AppProjectSpec{ + DestinationServiceAccounts: destinationServiceAccounts, + }, + } + app := &v1alpha1.Application{ + ObjectMeta: v1.ObjectMeta{ + Namespace: applicationNamespace, + Name: "testApp", + }, + Spec: v1alpha1.ApplicationSpec{ + Project: "testProj", + Destination: v1alpha1.ApplicationDestination{ + Server: destinationServerURL, + Namespace: destinationNamespace, + }, + }, + } + return &fixture{ + project: project, + application: app, + } + } + + t.Run("exact one match with multiple destination service accounts", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts and one exact match for application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-sa", + }, + { + Server: "https://abc.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-test-sa", + }, + { + Server: "https://cde.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "default-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and the right service account must be returned. + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("first match to be used when multiple matches are available", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts and multiple matches for application destination + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "guestbook", + DefaultServiceAccount: "guestbook-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and first matching service account should be used + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("first match to be used when glob pattern is used", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with a matching glob pattern and exact match + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "test*", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + assert.Equal(t, expectedSA, sa) + + // then, there should not be any error and the service account of the glob pattern, being the first match should be returned. + require.NoError(t, err) + }) + + t.Run("no match among a valid list", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with no match + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa", + }, + { + Server: "https://abc.svc.local", + Namespace: "testns", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://cde.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://xyz.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "" + expectedErr := "no matching service account found for destination server https://xyz.svc.local and namespace testns" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there an error with appropriate message must be returned + require.EqualError(t, err, expectedErr) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("match done via catch all glob pattern", func(t *testing.T) { + // given an application referring a project with multiple destination service accounts with matching catch all glob pattern + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://kubernetes.svc.local", + Namespace: "testns1", + DefaultServiceAccount: "test-sa-2", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "*", + Namespace: "*", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://localhost:6443" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:testns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and the service account of the glob pattern match must be returned. + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) + + t.Run("match done via invalid glob pattern", func(t *testing.T) { + // given an application referring a project with a destination service account having an invalid glob pattern for server + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "e[[a*", + Namespace: "test-ns", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://kubernetes.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there must be an error as the glob pattern is invalid. + require.ErrorContains(t, err, "invalid glob pattern for destination server") + assert.Equal(t, expectedSA, sa) + }) + + t.Run("sa specified with a namespace", func(t *testing.T) { + // given app sync impersonation feature is enabled and matching service account is prefixed with a namespace + t.Parallel() + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "https://abc.svc.local", + Namespace: "testns", + DefaultServiceAccount: "myns:test-sa", + }, + { + Server: "https://kubernetes.svc.local", + Namespace: "default", + DefaultServiceAccount: "default-sa", + }, + { + Server: "*", + Namespace: "*", + DefaultServiceAccount: "test-sa", + }, + } + destinationNamespace := "testns" + destinationServerURL := "https://abc.svc.local" + applicationNamespace := "argocd-ns" + expectedSA := "system:serviceaccount:myns:test-sa" + + f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace) + // when + sa, err := deriveServiceAccountToImpersonate(f.project, f.application) + + // then, there should not be any error and the service account with the given namespace prefix must be returned. + require.NoError(t, err) + assert.Equal(t, expectedSA, sa) + }) +} + +func TestSyncWithImpersonate(t *testing.T) { + type fixture struct { + project *v1alpha1.AppProject + application *v1alpha1.Application + controller *ApplicationController + } + + setup := func(impersonationEnabled bool, destinationNamespace, serviceAccountName string) *fixture { + app := newFakeApp() + app.Status.OperationState = nil + app.Status.History = nil + project := &v1alpha1.AppProject{ + ObjectMeta: v1.ObjectMeta{ + Namespace: test.FakeArgoCDNamespace, + Name: "default", + }, + Spec: v1alpha1.AppProjectSpec{ + DestinationServiceAccounts: []v1alpha1. + ApplicationDestinationServiceAccount{ + { + Server: "https://localhost:6443", + Namespace: destinationNamespace, + DefaultServiceAccount: serviceAccountName, + }, + }, + }, + } + additionalObjs := []runtime.Object{} + if serviceAccountName != "" { + syncServiceAccount := &corev1.ServiceAccount{ + ObjectMeta: v1.ObjectMeta{ + Name: serviceAccountName, + Namespace: test.FakeDestNamespace, + }, + } + additionalObjs = append(additionalObjs, syncServiceAccount) + } + data := fakeData{ + apps: []runtime.Object{app, project}, + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: "https://localhost:6443", + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}, + configMapData: map[string]string{ + "application.sync.impersonation.enabled": strconv.FormatBool(impersonationEnabled), + }, + additionalObjs: additionalObjs, + } + ctrl := newFakeController(&data, nil) + return &fixture{ + project: project, + application: app, + controller: ctrl, + } + } + + t.Run("sync with impersonation and no matching service account", func(t *testing.T) { + // given app sync impersonation feature is enabled with an application referring a project no matching service account + f := setup(true, test.FakeArgoCDNamespace, "") + opMessage := "failed to find a matching service account to impersonate: no matching service account found for destination server https://localhost:6443 and namespace fake-dest-ns" + + opState := &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Source: &v1alpha1.ApplicationSource{}, + }, + }, + Phase: common.OperationRunning, + } + // when + f.controller.appStateManager.SyncAppState(f.application, opState) + + // then, app sync should fail with expected error message in operation state + assert.Equal(t, common.OperationError, opState.Phase) + assert.Contains(t, opState.Message, opMessage) + }) + + t.Run("sync with impersonation and empty service account match", func(t *testing.T) { + // given app sync impersonation feature is enabled with an application referring a project matching service account that is an empty string + f := setup(true, test.FakeDestNamespace, "") + opMessage := "failed to find a matching service account to impersonate: default service account contains invalid chars ''" + + opState := &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Source: &v1alpha1.ApplicationSource{}, + }, + }, + Phase: common.OperationRunning, + } + // when + f.controller.appStateManager.SyncAppState(f.application, opState) + + // then app sync should fail with expected error message in operation state + assert.Equal(t, common.OperationError, opState.Phase) + assert.Contains(t, opState.Message, opMessage) + }) + + t.Run("sync with impersonation and matching sa", func(t *testing.T) { + // given app sync impersonation feature is enabled with an application referring a project matching service account + f := setup(true, test.FakeDestNamespace, "test-sa") + opMessage := "successfully synced (no more tasks)" + + opState := &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Source: &v1alpha1.ApplicationSource{}, + }, + }, + Phase: common.OperationRunning, + } + // when + f.controller.appStateManager.SyncAppState(f.application, opState) + + // then app sync should not fail + assert.Equal(t, common.OperationSucceeded, opState.Phase) + assert.Contains(t, opState.Message, opMessage) + }) + + t.Run("sync without impersonation", func(t *testing.T) { + // given app sync impersonation feature is disabled with an application referring a project matching service account + f := setup(false, test.FakeDestNamespace, "") + opMessage := "successfully synced (no more tasks)" + + opState := &v1alpha1.OperationState{ + Operation: v1alpha1.Operation{ + Sync: &v1alpha1.SyncOperation{ + Source: &v1alpha1.ApplicationSource{}, + }, + }, + Phase: common.OperationRunning, + } + // when + f.controller.appStateManager.SyncAppState(f.application, opState) + + // then application sync should pass using the control plane service account + assert.Equal(t, common.OperationSucceeded, opState.Phase) + assert.Contains(t, opState.Message, opMessage) + }) +} + func dig[T any](obj interface{}, path []interface{}) T { i := obj diff --git a/controller/testdata/job-failed-ignore-healthcheck.yaml b/controller/testdata/job-failed-ignore-healthcheck.yaml new file mode 100644 index 0000000000000..62a952203bd12 --- /dev/null +++ b/controller/testdata/job-failed-ignore-healthcheck.yaml @@ -0,0 +1,36 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + argocd.argoproj.io/ignore-healthcheck: "true" + labels: + job-name: fail + name: fail + namespace: argoci-workflows + selfLink: /apis/batch/v1/namespaces/argoci-workflows/jobs/fail +spec: + backoffLimit: 0 + completions: 1 + parallelism: 1 + template: + metadata: + creationTimestamp: null + labels: + job-name: fail + spec: + containers: + - command: + - sh + - -c + - exit 1 + image: alpine:latest + imagePullPolicy: Always + name: fail + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/controller/utils/log.go b/controller/utils/log.go new file mode 100644 index 0000000000000..3c5a244e73e6e --- /dev/null +++ b/controller/utils/log.go @@ -0,0 +1,17 @@ +package utils + +import ( + "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +// GetAppLog returns a logrus entry with fields set for the given application. +func GetAppLog(app *v1alpha1.Application) *logrus.Entry { + return logrus.WithFields(logrus.Fields{ + "application": app.Name, + "app-namespace": app.Namespace, + "app-qualified-name": app.QualifiedName(), + "project": app.Spec.Project, + }) +} diff --git a/docs/assets/keycloak-add-client-pkce_2.png b/docs/assets/keycloak-add-client-pkce_2.png new file mode 100644 index 0000000000000..eaade14737813 Binary files /dev/null and b/docs/assets/keycloak-add-client-pkce_2.png differ diff --git a/docs/assets/keycloak-authentication-successful.png b/docs/assets/keycloak-authentication-successful.png new file mode 100644 index 0000000000000..7745773967026 Binary files /dev/null and b/docs/assets/keycloak-authentication-successful.png differ diff --git a/docs/assets/keycloak-configure-client-pkce.png b/docs/assets/keycloak-configure-client-pkce.png new file mode 100644 index 0000000000000..6b6e50cefc8c1 Binary files /dev/null and b/docs/assets/keycloak-configure-client-pkce.png differ diff --git a/docs/assets/keycloak-configure-client-pkce_2.png b/docs/assets/keycloak-configure-client-pkce_2.png new file mode 100644 index 0000000000000..ca9ec13c49600 Binary files /dev/null and b/docs/assets/keycloak-configure-client-pkce_2.png differ diff --git a/docs/assets/keycloak-configure-client.png b/docs/assets/keycloak-configure-client.png index cd711dfd602bf..9f967dc33ab0b 100644 Binary files a/docs/assets/keycloak-configure-client.png and b/docs/assets/keycloak-configure-client.png differ diff --git a/docs/assets/orphaned-resources.png b/docs/assets/orphaned-resources.png index b23d1b26b62e1..383d88128d3ba 100644 Binary files a/docs/assets/orphaned-resources.png and b/docs/assets/orphaned-resources.png differ diff --git a/docs/assets/versions.js b/docs/assets/versions.js index b9f0b13e8d013..c1a99d0287c6a 100644 --- a/docs/assets/versions.js +++ b/docs/assets/versions.js @@ -4,6 +4,8 @@ const observerOptions = { subtree: true }; +const VERSION_REGEX = /\/en\/(release-(?:v\d+|[\d\.]+|\w+)|latest|stable)\//; + const observerCallback = function(mutationsList, observer) { for (let mutation of mutationsList) { if (mutation.type === 'childList') { @@ -20,7 +22,7 @@ const observer = new MutationObserver(observerCallback); observer.observe(targetNode, observerOptions); function getCurrentVersion() { - const currentVersion = window.location.href.match(/\/en\/(release-(?:v\d+|[\d\.]+|\w+)|latest|stable)\//); + const currentVersion = window.location.href.match(VERSION_REGEX); if (currentVersion && currentVersion.length > 1) { return currentVersion[1]; } @@ -32,23 +34,41 @@ function initializeVersionDropdown() { window[callbackName] = function(response) { const div = document.createElement('div'); div.innerHTML = response.html; - document.querySelector(".md-header__inner > .md-header__title").appendChild(div); + const headerTitle = document.querySelector(".md-header__inner > .md-header__title"); + if (headerTitle) { + headerTitle.appendChild(div); + } + const container = div.querySelector('.rst-versions'); + if (!container) return; // Exit if container not found + + // Add caret icon var caret = document.createElement('div'); caret.innerHTML = ""; caret.classList.add('dropdown-caret'); - div.querySelector('.rst-current-version').appendChild(caret); + const currentVersionElem = div.querySelector('.rst-current-version'); + if (currentVersionElem) { + currentVersionElem.appendChild(caret); + } - div.querySelector('.rst-current-version').addEventListener('click', function() { - container.classList.toggle('shift-up'); - }); + // Add click listener to toggle dropdown + if (currentVersionElem && container) { + currentVersionElem.addEventListener('click', function() { + container.classList.toggle('shift-up'); + }); + } + + // Sorting Logic + sortVersionLinks(container); }; + // Load CSS var CSSLink = document.createElement('link'); CSSLink.rel = 'stylesheet'; CSSLink.href = '/assets/versions.css'; document.getElementsByTagName('head')[0].appendChild(CSSLink); + // Load JSONP Script var script = document.createElement('script'); const currentVersion = getCurrentVersion(); script.src = 'https://argo-cd.readthedocs.io/_/api/v2/footer_html/?' + @@ -56,6 +76,63 @@ function initializeVersionDropdown() { document.getElementsByTagName('head')[0].appendChild(script); } +// Function to sort version links +function sortVersionLinks(container) { + // Find all
elements within the container + const dlElements = container.querySelectorAll('dl'); + + dlElements.forEach(dl => { + const ddElements = Array.from(dl.querySelectorAll('dd')); + + // Check if ddElements contain version links + const isVersionDl = ddElements.some(dd => { + const link = dd.querySelector('a'); + return VERSION_REGEX.test(link?.getAttribute?.('href')); + }); + + // This dl contains version links, proceed to sort + if (isVersionDl) { + // Define sorting criteria + ddElements.sort((a, b) => { + const aText = a.textContent.trim().toLowerCase(); + const bText = b.textContent.trim().toLowerCase(); + + // Prioritize 'latest' and 'stable' + if (aText === 'latest') return -1; + if (bText === 'latest') return 1; + if (aText === 'stable') return -1; + if (bText === 'stable') return 1; + + // Extract version numbers (e.g., release-2.9) + const aVersionMatch = aText.match(/release-(\d+(\.\d+)*)/); + const bVersionMatch = bText.match(/release-(\d+(\.\d+)*)/); + + if (aVersionMatch && bVersionMatch) { + const aVersion = aVersionMatch[1].split('.').map(Number); + const bVersion = bVersionMatch[1].split('.').map(Number); + + for (let i = 0; i < Math.max(aVersion.length, bVersion.length); i++) { + const aNum = aVersion[i] || 0; + const bNum = bVersion[i] || 0; + if (aNum > bNum) return -1; + if (aNum < bNum) return 1; + } + return 0; + } + + // Fallback to alphabetical order + return aText.localeCompare(bText); + }); + + // Remove existing
elements + ddElements.forEach(dd => dl.removeChild(dd)); + + // Append sorted
elements + ddElements.forEach(dd => dl.appendChild(dd)); + } + }); +} + // VERSION WARNINGS window.addEventListener("DOMContentLoaded", function() { var margin = 30; diff --git a/docs/developer-guide/architecture/authz-authn.md b/docs/developer-guide/architecture/authz-authn.md index af32a9176eec9..921b744f2ea8a 100644 --- a/docs/developer-guide/architecture/authz-authn.md +++ b/docs/developer-guide/architecture/authz-authn.md @@ -7,7 +7,7 @@ enforced. ## Logical layers -The diagram bellow suggests 4 different logical layers (represented by +The diagram below suggests 4 different logical layers (represented by 4 boxes: HTTP, gRPC, AuthN and AuthZ) inside Argo CD API server that collaborate to provide authentication and authorization. diff --git a/docs/developer-guide/code-contributions.md b/docs/developer-guide/code-contributions.md index 2d28aaa956b48..2c8c9bdac7157 100644 --- a/docs/developer-guide/code-contributions.md +++ b/docs/developer-guide/code-contributions.md @@ -13,11 +13,6 @@ Before submitting code for a new feature (and also, to some extent, for more com [raise an Enhancement Proposal or Bug Issue](https://github.com/argoproj/argo-cd/issues/new/choose) first. -Each enhancement proposal needs to go through our -[triage process](#triage-process) -before we accept code contributions. To facilitate triage and to provide transparency, we use -[this GitHub project](https://github.com/orgs/argoproj/projects/18) to keep track of this process' outcome. - _Please_ do not spend too much time on larger features or refactorings before the corresponding enhancement has been triaged. This may save everyone some amount of frustration and time, as the enhancement proposal might be rejected, and the code would never get merged. However, sometimes it's helpful to have some PoC code along with a proposal. We will do our best to triage incoming enhancement proposals quickly, with one of the following outcomes: diff --git a/docs/developer-guide/contributors-quickstart.md b/docs/developer-guide/contributors-quickstart.md index 68cda35b6d08e..5544742b7a06b 100644 --- a/docs/developer-guide/contributors-quickstart.md +++ b/docs/developer-guide/contributors-quickstart.md @@ -7,24 +7,59 @@ and the [toolchain guide](toolchain-guide.md). ## Getting Started +### Prerequisites + +Before starting, ensure you have the following tools installed with the specified minimum versions: + +* Git (v2.0.0+) +* Go (version specified in `go.mod` - check with `go version`) +* Docker (v20.10.0+) Or Podman (v3.0.0+) +* Kind (v0.11.0+) Or Minikube (v1.23.0+) +* Yarn (v1.22.0+) +* Goreman (latest version) + +### Fork and Clone the Repository + +1. Fork the Argo CD repository to your personal Github Account + +2. Clone the forked repository: +```shell +mkdir -p $GOPATH/src/github.com/argoproj/ +cd $GOPATH/src/github.com/argoproj/ +git clone https://github.com/YOUR-USERNAME/argo-cd.git +``` + +3. Add the upstream remote for rebasing: +```shell +cd argo-cd +git remote add upstream https://github.com/argoproj/argo-cd.git +``` + +### Install Required Tools + +1. Install development tools: +```shell +make install-go-tools-local +make install-code-gen-tools-local +``` + ### Install Go Install Go with a version equal to or greater than the version listed in `go.mod` (verify go version with `go version`). -### Clone the Argo CD repo -```shell -mkdir -p $GOPATH/src/github.com/argoproj/ && -cd $GOPATH/src/github.com/argoproj && -git clone https://github.com/argoproj/argo-cd.git -``` +### Install Docker or Podman -### Install Docker +#### Installation guide for docker: +#### Installation guide for podman: + + + ### Install or Upgrade a Tool for Running Local Clusters (e.g. kind or minikube) #### Installation guide for kind: @@ -48,6 +83,12 @@ Or, if you are using minikube: minikube start ``` +Or, if you are using minikube with podman driver: + +```shell +minikube start --driver=podman +``` + ### Install Argo CD ```shell @@ -77,6 +118,13 @@ cd argo-cd make start-local ARGOCD_GPG_ENABLED=false ``` +By default, Argo CD uses Docker. To use Podman instead, set the `DOCKER` environment variable to `podman` before running the `make` command: + +```shell +cd argo-cd +DOCKER=podman make start-local ARGOCD_GPG_ENABLED=false +``` + - Navigate to [localhost:4000](http://localhost:4000) in your browser to load the Argo CD UI - It may take a few minutes for the UI to be responsive @@ -84,8 +132,40 @@ make start-local ARGOCD_GPG_ENABLED=false If the UI is not working, check the logs from `make start-local`. The logs are `DEBUG` level by default. If the logs are too noisy to find the problem, try editing log levels for the commands in the `Procfile` in the root of the Argo CD repo. +## Common Make Targets + +Here are some frequently used make targets: + +* `make start-local` - Start Argo CD locally +* `make test` - Run unit tests +* `make test-e2e` - Run end-to-end tests +* `make lint` - Run linting +* `make serve-docs` - Serve documentation locally +* `make pre-commit-local` - Run pre-commit checks locally +* `make build` - Build Argo CD binaries + ## Making Changes +### Before Submitting a PR + +1. Rebase your branch against upstream main: +```shell +git fetch upstream +git rebase upstream/main +``` + +2. Run pre-commit checks: +```shell +make pre-commit-local +``` + +### Docs Changes + +Modifying the docs auto-reloads the changes on the [documentation website](https://argo-cd.readthedocs.io/) that can be locally built using `make serve-docs` command. +Once running, you can view your locally built documentation on port 8000. + +Read more about this [here](https://argo-cd.readthedocs.io/en/latest/developer-guide/docs-site/). + ### UI Changes Modifying the User-Interface (by editing .tsx or .scss files) auto-reloads the changes on port 4000. diff --git a/docs/developer-guide/docs-site.md b/docs/developer-guide/docs-site.md index 43b3fba747186..8528082b44a68 100644 --- a/docs/developer-guide/docs-site.md +++ b/docs/developer-guide/docs-site.md @@ -17,6 +17,25 @@ Before submitting a PR build the website, to verify that there are no errors bui make build-docs ``` +If you want to build and test the site directly on your local machine without the use of docker container, follow the below steps: + +1. Install the `mkdocs` using the `pip` command + ```bash + pip install mkdocs + ``` +2. Install the required dependencies using the below command + ```bash + pip install $(mkdocs get-deps) + ``` +3. Build the docs site locally from the root + ```bash + make build-docs-local + ``` +4. Start the docs site locally + ```bash + make serve-docs-local + ``` + ## Analytics !!! tip diff --git a/docs/developer-guide/extensions/proxy-extensions.md b/docs/developer-guide/extensions/proxy-extensions.md index ab4d89c7f8e32..57166ef071642 100644 --- a/docs/developer-guide/extensions/proxy-extensions.md +++ b/docs/developer-guide/extensions/proxy-extensions.md @@ -1,5 +1,8 @@ # Proxy Extensions -*Current Status: [Alpha][1] (Since v2.7.0)* + +!!! warning "Alpha Feature (Since 2.7.0)" + This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha) + feature. It may be removed in future releases or modified in backwards-incompatible ways. ## Overview @@ -60,7 +63,38 @@ data: server: https://some-cluster ``` -Note: There is no need to restart Argo CD Server after modifiying the +Proxy extensions can also be provided individually using dedicated +Argo CD configmap keys for better GitOps operations. The example below +demonstrates how to configure the same hypothetical httpbin config +above using a dedicated key: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm + namespace: argocd +data: + extension.config.httpbin: | + connectionTimeout: 2s + keepAlive: 15s + idleConnectionTimeout: 60s + maxIdleConnections: 30 + services: + - url: http://httpbin.org + headers: + - name: some-header + value: '$some.argocd.secret.key' + cluster: + name: some-cluster + server: https://some-cluster +``` + +Attention: Extension names must be unique in the Argo CD configmap. If +duplicated keys are found, the Argo CD API server will log an error +message and no proxy extension will be registered. + +Note: There is no need to restart Argo CD Server after modifying the `extension.config` entry in Argo CD configmap. Changes will be automatically applied. A new proxy registry will be built making all new incoming extensions requests (`/extensions/*`) to diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index 2db177eb90984..bda586a97e0d6 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -6,7 +6,7 @@ These are the upcoming releases dates: -| Release | Release Candidate 1 | General Availability | Release Champion | Release Approver |Checklist | +| Release | Release Candidate 1 | General Availability | Release Champion | Release Approver | Checklist | |---------|-----------------------|----------------------|-------------------------------------------------------|-------------------------------------------------------|---------------------------------------------------------------| | v2.6 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) | | v2.7 | Monday, Mar. 20, 2023 | Monday, May 1, 2023 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/12762) | @@ -14,10 +14,10 @@ These are the upcoming releases dates: | v2.9 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | | v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | [Katie Lamkin](https://github.com/kmlamkin9) | | [checklist](https://github.com/argoproj/argo-cd/issues/16339) | | v2.11 | Friday, Apr. 5, 2024 | Monday, May 6, 2024 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/17726) | -| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) | +| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) | | v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | [Regina Voloshin](https://github.com/reggie-k) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19513) | -| v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | | | | -| v2.15 | Monday, Mar. 17, 2025 | Monday, May 5, 2025 | | | | +| v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | [Ryan Umstead](https://github.com/rumstead) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/20869) | +| v2.15 | Monday, Mar. 17, 2025 | Monday, May 5, 2025 | | | | Actual release dates might differ from the plan by a few days. diff --git a/docs/developer-guide/test-e2e.md b/docs/developer-guide/test-e2e.md index 477723016bd75..a1ddec8058f0f 100644 --- a/docs/developer-guide/test-e2e.md +++ b/docs/developer-guide/test-e2e.md @@ -1,21 +1,21 @@ # E2E Tests -The directory contains E2E tests and test applications. The test assume that Argo CD services are installed into `argocd-e2e` namespace or cluster in current context. One throw-away -namespace `argocd-e2e***` is created prior to tests execute. The throw-away namespace is used as a target namespace for test applications. +The test [directory](https://github.com/argoproj/argo-cd/tree/master/test) contains E2E tests and test applications. The tests assume that Argo CD services are installed into `argocd-e2e` namespace or cluster in current context. A throw-away +namespace `argocd-e2e***` is created prior to the execution of the tests. The throw-away namespace is used as a target namespace for test applications. -The `test/e2e/testdata` directory contains various Argo CD applications. Before test execution directory is copies into `/tmp/argocd-e2e***` temp directory and used in tests as a +The [/test/e2e/testdata](https://github.com/argoproj/argo-cd/tree/master/test/e2e/testdata) directory contains various Argo CD applications. Before test execution directory is copies into `/tmp/argocd-e2e***` temp directory and used in tests as a Git repository via file url: `file:///tmp/argocd-e2e***`. ## Running Tests Locally -1. Start the e2e version `make start-e2e` -1. Run the tests: `make test-e2e` +1. Start the e2e version `make start-e2e` +2. Run the tests: `make test-e2e` You can observe the tests by using the UI [http://localhost:8080/applications](http://localhost:8080/applications) with username `"admin"` and password `"password"`. ## Configuration of E2E Tests execution -The Makefile's `start-e2e` target starts instances of ArgoCD on your local machine, of which the most will require a network listener. If for whatever reason you already have network services on your machine listening on the same ports, the e2e tests will not be able to run. You can derive from the defaults by setting the following environment variables before you run `make start-e2e`: +The Makefile's `start-e2e` target starts instances of ArgoCD on your local machine, of which the most will require a network listener. If, for any reason, your machine already has network services listening on the same ports, then the e2e tests will not run. You can derive from the defaults by setting the following environment variables before you run `make start-e2e`: * `ARGOCD_E2E_APISERVER_PORT`: Listener port for `argocd-server` (default: `8080`) * `ARGOCD_E2E_REPOSERVER_PORT`: Listener port for `argocd-reposerver` (default: `8081`) diff --git a/docs/developer-guide/use-gitpod.md b/docs/developer-guide/use-gitpod.md index 12b2c49eabf40..36f783bdc99dc 100644 --- a/docs/developer-guide/use-gitpod.md +++ b/docs/developer-guide/use-gitpod.md @@ -1,7 +1,7 @@ # Use Gitpod [Gitpod](https://www.gitpod.io/) is an open-source platform for automated and ready-to-code development environments. -GitPod is probably the easiest way to get ready to use development environment with the most tools that are required +Gitpod is probably the easiest way to get ready to use development environment with the most tools that are required for Argo CD development. ## How To Use It diff --git a/docs/faq.md b/docs/faq.md index e98ca95f556b6..44c3e25902c82 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -151,10 +151,10 @@ The default polling interval is 3 minutes (180 seconds) with a configurable jitt You can change the setting by updating the `timeout.reconciliation` value and the `timeout.reconciliation.jitter` in the [argocd-cm](https://github.com/argoproj/argo-cd/blob/2d6ce088acd4fb29271ffb6f6023dbb27594d59b/docs/operator-manual/argocd-cm.yaml#L279-L282) config map. If there are any Git changes, Argo CD will only update applications with the [auto-sync setting](user-guide/auto_sync.md) enabled. If you set it to `0` then Argo CD will stop polling Git repositories automatically and you can only use alternative methods such as [webhooks](operator-manual/webhook.md) and/or manual syncs for deploying applications. -## Why Are My Resource Limits `Out Of Sync`? +## Why is my ArgoCD application `Out Of Sync` when there are no actual changes to the resource limits (or other fields with unit values)? -Kubernetes has normalized your resource limits when they are applied, and then Argo CD has then compared the version in -your generated manifests to the normalized one is Kubernetes - they won't match. +Kubernetes has normalized your resource limits when they are applied, and then Argo CD has compared the version in +your generated manifests from git to the normalized ones in the Kubernetes cluster - they may not match. E.g. @@ -162,9 +162,9 @@ E.g. * `'0.1'` normalized to `'100m'` * `'3072Mi'` normalized to `'3Gi'` * `3072` normalized to `'3072'` (quotes added) +* `8760h` normalized to `8760h0m0s` -To fix this use diffing -customizations [settings](./user-guide/diffing.md#known-kubernetes-types-in-crds-resource-limits-volume-mounts-etc). +To fix this use [diffing customizations](./user-guide/diffing.md#known-kubernetes-types-in-crds-resource-limits-volume-mounts-etc). ## How Do I Fix `invalid cookie, longer than max length 4093`? diff --git a/docs/getting_started.md b/docs/getting_started.md index ce0d9688e7963..596251b3c28b0 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -141,6 +141,9 @@ service account token to perform its management tasks (i.e. deploy/monitoring). An example repository containing a guestbook application is available at [https://github.com/argoproj/argocd-example-apps.git](https://github.com/argoproj/argocd-example-apps.git) to demonstrate how Argo CD works. +!!! note + Note: The following example application may only be compatible with AMD64 architecture. If you are running on a different architecture (such as ARM64 or ARMv7), you may encounter issues with dependencies or container images that are not built for your platform. Consider verifying the compatibility of the application or building architecture-specific images if necessary. + ### Creating Apps Via CLI First we need to set the current namespace to argocd running the following command: @@ -157,7 +160,7 @@ argocd app create guestbook --repo https://github.com/argoproj/argocd-example-ap ### Creating Apps Via UI -Open a browser to the Argo CD external UI, and login by visiting the IP/hostname in a browser and use the credentials set in step 4. +Open a browser to the Argo CD external UI, and login by visiting the IP/hostname in a browser and use the credentials set in step 4 or locally as explained in [Try Argo CD Locally](try_argo_cd_locally.md). After logging in, click the **+ New App** button as shown below: diff --git a/docs/index.md b/docs/index.md index ddb17c2bdc36a..05a506395df21 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,7 +40,7 @@ the desired application state. Kubernetes manifests can be specified in several * Any custom config management tool configured as a config management plugin Argo CD automates the deployment of the desired application states in the specified target environments. -Application deployments can track updates to branches, tags, or pinned to a specific version of +Application deployments can track updates to branches, tags, or be pinned to a specific version of manifests at a Git commit. See [tracking strategies](user-guide/tracking_strategies.md) for additional details about the different tracking strategies available. diff --git a/docs/operator-manual/app-sync-using-impersonation.md b/docs/operator-manual/app-sync-using-impersonation.md index 9314f0b376b8e..92949a80dc8a0 100644 --- a/docs/operator-manual/app-sync-using-impersonation.md +++ b/docs/operator-manual/app-sync-using-impersonation.md @@ -1,7 +1,10 @@ # Application Sync using impersonation -!!! warning "Alpha Feature" - This is an experimental, alpha-quality feature that allows you to control the service account used for the sync operation. The configured service account, could have lesser privileges required for creating resources compared to the highly privileged access required for the control plane operations. +!!! warning "Alpha Feature (Since 2.13.0)" + This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha) + feature that allows you to control the service account used for the sync operation. The configured service account + could have lesser privileges required for creating resources compared to the highly privileged access required for + the control plane operations. !!! warning Please read this documentation carefully before you enable this feature. Misconfiguration could lead to potential security issues. @@ -94,7 +97,7 @@ spec: sourceRepos: - '*' destinations: - - * + - '*' destinationServiceAccounts: - server: https://kubernetes.default.svc namespace: guestbook diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index 051ca6a1755e3..b38d7fddd50c5 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -85,6 +85,9 @@ spec: # Skip custom resource definition installation if chart contains custom resource definitions. Defaults to false skipCrds: false + + # Skip schema validation if chart contains JSON schema validation. Defaults to false + skipSchemaValidation: false # Optional Helm version to template with. If omitted it will fall back to look at the 'apiVersion' in Chart.yaml # and decide which Helm binary to use automatically. This field can be either 'v2' or 'v3'. diff --git a/docs/operator-manual/applicationset.yaml b/docs/operator-manual/applicationset.yaml index 88264493e248d..dbe36e076ca2e 100644 --- a/docs/operator-manual/applicationset.yaml +++ b/docs/operator-manual/applicationset.yaml @@ -3,16 +3,6 @@ kind: ApplicationSet metadata: name: test-hello-world-appset namespace: argocd - # To preserve this annotation and label we can use the preservedFields property - preservedFields: - # This annotation and label exists only on this Application, and not in - # the parent ApplicationSet template: - # ignoreApplicationDifferences is the preferred way to accomplish this now. - annotations: - my-custom-annotation: some-value - labels: - my-custom-label: some-value - spec: generators: @@ -168,29 +158,17 @@ spec: applicationsSync: create-only # Prevents ApplicationSet controller from deleting Applications. Update is allowed - # applicationsSync: create-update + # applicationsSync: create-update # Prevents ApplicationSet controller from modifying Applications. Delete is allowed. - # applicationsSync: create-delete + # applicationsSync: create-delete - syncOptions: - - CreateNamespace=true # Prevent an Application's child resources from being deleted, when the parent Application is deleted preserveResourcesOnDeletion: true - # which fields of the ApplicationSet should be ignored when comparing Applications. - ignoreApplicationDifferences: - - jsonPointers: - - /spec/source/targetRevision - - name: some-app - jqExpressions: - - .spec.source.helm.values - strategy: - # This field lets you define fields which should be ignored when applying Application resources. This is helpful if you - # want to use ApplicationSets to create apps, but also want to allow users to modify those apps without having their - # changes overwritten by the ApplicationSet. - # This update strategy allows you to group Applications by labels present on the generated Application resources + # The RollingSync update strategy allows you to group Applications by labels present on the generated Application resources + # See documentation for "Progressive Syncs" type: RollingSync rollingSync: steps: @@ -214,6 +192,13 @@ spec: - env-prod maxUpdate: 10% # maxUpdate supports both integer and percentage string values (rounds down, but floored at 1 Application for >0%) + # Define annotations and labels of the Application that this ApplicationSet will ignore + # ignoreApplicationDifferences is the preferred way to accomplish this now. + preservedFields: + annotations: [ some-annotation-key ] + labels: [ some-label-key ] + + # Define fields of the that should be ignored when comparing Applications ignoreApplicationDifferences: - jsonPointers: - /spec/source/targetRevision @@ -311,4 +296,4 @@ spec: operator: In values: - https://kubernetes.default.svc - - https://some-other-cluster \ No newline at end of file + - https://some-other-cluster diff --git a/docs/operator-manual/applicationset/Application-Deletion.md b/docs/operator-manual/applicationset/Application-Deletion.md index b59a556ec7f40..2f13ccb1add71 100644 --- a/docs/operator-manual/applicationset/Application-Deletion.md +++ b/docs/operator-manual/applicationset/Application-Deletion.md @@ -8,7 +8,7 @@ All `Application` resources created by the ApplicationSet controller (from an Ap The end result is that when an ApplicationSet is deleted, the following occurs (in rough order): - The `ApplicationSet` resource itself is deleted -- Any `Application` resources that were created from this `ApplicationSet` (as identified by owner reference) +- Any `Application` resources that were created from this `ApplicationSet` (as identified by owner reference) will be deleted - Any deployed resources (`Deployments`, `Services`, `ConfigMaps`, etc) on the managed cluster, that were created from that `Application` resource (by Argo CD), will be deleted. - Argo CD is responsible for handling this deletion, via [the deletion finalizer](../../../user-guide/app_deletion/#about-the-deletion-finalizer). - To preserve deployed resources, set `.syncPolicy.preserveResourcesOnDeletion` to true in the ApplicationSet. @@ -26,4 +26,4 @@ kubectl delete ApplicationSet (NAME) --cascade=orphan !!! warning Even if using a non-cascaded delete, the `resources-finalizer.argocd.argoproj.io` is still specified on the `Application`. Thus, when the `Application` is deleted, all of its deployed resources will also be deleted. (The lifecycle of the Application, and its *child* objects, are still equivalent.) - To prevent the deletion of the resources of the Application, such as Services, Deployments, etc, set `.syncPolicy.preserveResourcesOnDeletion` to true in the ApplicationSet. This syncPolicy parameter prevents the finalizer from being added to the Application. \ No newline at end of file + To prevent the deletion of the resources of the Application, such as Services, Deployments, etc, set `.syncPolicy.preserveResourcesOnDeletion` to true in the ApplicationSet. This syncPolicy parameter prevents the finalizer from being added to the Application. diff --git a/docs/operator-manual/applicationset/Appset-Any-Namespace.md b/docs/operator-manual/applicationset/Appset-Any-Namespace.md index f6124f098cb6d..01efe576d049c 100644 --- a/docs/operator-manual/applicationset/Appset-Any-Namespace.md +++ b/docs/operator-manual/applicationset/Appset-Any-Namespace.md @@ -1,6 +1,8 @@ # ApplicationSet in any namespace -**Current feature state**: Beta +!!! warning "Beta Feature (Since v2.8.0)" + This feature is in the [Beta](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#beta) stage. + It is generally considered stable, but there may be unhandled edge cases. !!! warning Please read this documentation carefully before you enable this feature. Misconfiguration could lead to potential security issues. @@ -77,6 +79,29 @@ data: If you do not intend to allow users to use the SCM or PR generators, you can disable them entirely by setting the environment variable `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS` to argocd-cmd-params-cm `applicationsetcontroller.enable.scm.providers` to `false`. +#### `tokenRef` Restrictions + +It is **highly recommended** to enable SCM Providers secrets restrictions to avoid any secrets exfiltration. This +recommendation applies even when AppSets-in-any-namespace is disabled, but is especially important when it is enabled, +since non-Argo-admins may attempt to reference out-of-bounds secrets in the `argocd` namespace from an AppSet +`tokenRef`. + +When this mode is enabled, the referenced secret must have a label `argocd.argoproj.io/secret-type` with value +`scm-creds`. + +To enable this mode, set the `ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE` environment variable to `true` in the +`argocd-application-controller` deployment. You can do this by adding the following to your `argocd-cmd-paramscm` +ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm +data: + applicationsetcontroller.tokenref.strict.mode: "true" +``` + ### Overview In order for an ApplicationSet to be managed and reconciled outside the Argo CD's control plane namespace, two prerequisites must match: diff --git a/docs/operator-manual/applicationset/Generators-Cluster.md b/docs/operator-manual/applicationset/Generators-Cluster.md index de769b94deed9..5b70cc206e98c 100644 --- a/docs/operator-manual/applicationset/Generators-Cluster.md +++ b/docs/operator-manual/applicationset/Generators-Cluster.md @@ -9,6 +9,7 @@ It automatically provides the following parameter values to the Application temp - `name` - `nameNormalized` *('name' but normalized to contain only lowercase alphanumeric characters, '-' or '.')* - `server` +- `project` *(the Secret's 'project' field, if present; otherwise, it defaults to '')* - `metadata.labels.` *(for each label in the Secret)* - `metadata.annotations.` *(for each annotation in the Secret)* @@ -252,3 +253,63 @@ spec: server: '{{.values.clusterName}}' namespace: guestbook ``` +### Gather cluster information as a flat list + +You may sometimes need to gather your clusters information, without having to deploy one application per cluster found. +For that, you can use the option `flatList` in the cluster generator. + +Here is an example of cluster generator using this option: +```yaml +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: + selector: + matchLabels: + type: 'staging' + flatList: true + template: + metadata: + name: 'flat-list-guestbook' + spec: + project: "my-project" + source: + repoURL: https://github.com/argoproj/argocd-example-apps/ + # The cluster values field for each generator will be substituted here: + targetRevision: 'HEAD' + path: helm-guestbook + helm: + values: | + clusters: + {{- range .clusters }} + - name: {{ .name }} + {{- end }} + destination: + # In this case this is equivalent to just using {{name}} + server: 'my-cluster' + namespace: guestbook +``` + +Given that you have two cluster secrets matching with names cluster1 and cluster2, this would generate the **single** following Application: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: flat-list-guestbook + namespace: guestbook +spec: + project: "my-project" + source: + repoURL: https://github.com/argoproj/argocd-example-apps/ + targetRevision: 'HEAD' + path: helm-guestbook + helm: + values: | + clusters: + - name: cluster1 + - name: cluster2 +``` + +In case you are using several cluster generators, each with the flatList option, one Application would be generated by cluster generator, as we can't simply merge values and templates that would potentially differ in each generator. \ No newline at end of file diff --git a/docs/operator-manual/applicationset/Generators-Git.md b/docs/operator-manual/applicationset/Generators-Git.md index 19564970749a6..569eb60034389 100644 --- a/docs/operator-manual/applicationset/Generators-Git.md +++ b/docs/operator-manual/applicationset/Generators-Git.md @@ -443,3 +443,9 @@ stringData: ``` After saving, please restart the ApplicationSet pod for the changes to take effect. + +## Repository credentials for ApplicationSets +If your [ApplicationSets](index.md) uses a repository where you need credentials to be able to access it, you need to add the repository as a "non project scoped" repository. +- When doing that through the UI, set this to a **blank** value in the dropdown menu. +- When doing that through the CLI, make sure you **DO NOT** supply the parameter `--project` ([argocd repo add docs](../../user-guide/commands/argocd_repo_add.md)) +- When doing that declaratively, make sure you **DO NOT** have `project:` defined under `stringData:` ([complete yaml example](../argocd-repositories-yaml.md)) diff --git a/docs/operator-manual/applicationset/Generators-Post-Selector.md b/docs/operator-manual/applicationset/Generators-Post-Selector.md index 5a07cf1db425c..03959175893cb 100644 --- a/docs/operator-manual/applicationset/Generators-Post-Selector.md +++ b/docs/operator-manual/applicationset/Generators-Post-Selector.md @@ -40,12 +40,12 @@ spec: - cluster: engineering-prod url: https://kubernetes.default.svc env: prod - selector: - matchExpressions: - - key: env - operator: In - values: - - staging + selector: + matchExpressions: + - key: env + operator: In + values: + - staging ``` Valid `operators` include `In`, `NotIn`, `Exists`, and `DoesNotExist`. The `values` set must be non-empty in the case of `In` and `NotIn`. diff --git a/docs/operator-manual/applicationset/Progressive-Syncs.md b/docs/operator-manual/applicationset/Progressive-Syncs.md index edfe0dad101f2..63066ffe3511a 100644 --- a/docs/operator-manual/applicationset/Progressive-Syncs.md +++ b/docs/operator-manual/applicationset/Progressive-Syncs.md @@ -1,7 +1,9 @@ # Progressive Syncs -!!! warning "Alpha Feature" - This is an experimental, alpha-quality feature that allows you to control the order in which the ApplicationSet controller will create or update the Applications owned by an ApplicationSet resource. It may be removed in future releases or modified in backwards-incompatible ways. +!!! warning "Alpha Feature (Since v2.6.0)" + This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha) + feature that allows you to control the order in which the ApplicationSet controller will create or update the Applications + owned by an ApplicationSet resource. It may be removed in future releases or modified in backwards-incompatible ways. ## Use Cases The Progressive Syncs feature set is intended to be light and flexible. The feature only interacts with the health of managed Applications. It is not intended to support direct integrations with other Rollout controllers (such as the native ReplicaSet controller or Argo Rollouts). @@ -42,6 +44,7 @@ When the ApplicationSet changes, the changes will be applied to each group of Ap * Sync operations are triggered the same way as if they were triggered by the UI or CLI (by directly setting the `operation` status field on the Application resource). This means that a RollingSync will respect sync windows just as if a user had clicked the "Sync" button in the Argo UI. * When a sync is triggered, the sync is performed with the same syncPolicy configured for the Application. For example, this preserves the Application's retry settings. * If an Application is considered "Pending" for `applicationsetcontroller.default.application.progressing.timeout` seconds, the Application is automatically moved to Healthy status (default 300). +* If an Application is not selected in any step, it will be excluded from the rolling sync and needs to be manually synced through the CLI or UI. #### Example The following example illustrates how to stage a progressive sync over Applications with explicitly configured environment labels. diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index a8d3be645bcfb..68b4c0c7302b9 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -107,8 +107,8 @@ data: - /spec/replicas # Enable resource.customizations.ignoreResourceUpdates rules. If "false," those rules are not applied, and all updates - # to resources are applied to the cluster cache. Default is false. - resource.ignoreResourceUpdatesEnabled: "false" + # to resources are applied to the cluster cache. Default is true. + resource.ignoreResourceUpdatesEnabled: "true" # Configuration to define customizations ignoring differences during watched resource updates to skip application reconciles. resource.customizations.ignoreResourceUpdates.all: | @@ -222,6 +222,9 @@ data: clusters: - "*.local" + # An optional comma-separated list of annotation keys to mask in UI/CLI on secrets + resource.sensitive.mask.annotations: openshift.io/token-secret.value,api-key + # An optional comma-separated list of metadata.labels to observe in the UI. resource.customLabels: tier @@ -283,6 +286,9 @@ data: # - annotation+label : Also uses an annotation for tracking, but additionally labels the resource with the application name application.resourceTrackingMethod: annotation + # Optional installation id. Allows to have multiple installations of Argo CD in the same cluster. + installationID: "my-unique-id" + # disables admin user. Admin is enabled by default admin.enabled: "false" # add an additional local user with apiKey and login capabilities @@ -322,21 +328,22 @@ data: # Application reconciliation timeout is the max amount of time required to discover if a new manifests version got # published to the repository. Reconciliation by timeout is disabled if timeout is set to 0. Three minutes by default. - # > Note: argocd-repo-server deployment must be manually restarted after changing the setting. + # > Note: The argocd-repo-server deployment and the argocd-application-controller statefulset (or deployment, if + # configured) must be manually restarted after changing the setting. timeout.reconciliation: 180s # With a large number of applications, the periodic refresh for each application can cause a spike in the refresh queue # and can cause a spike in the repo-server component. To avoid this, you can set a jitter to the sync timeout, which will # spread out the refreshes and give time to the repo-server to catch up. The jitter is the maximum duration that can be # added to the sync timeout. So, if the sync timeout is 3 minutes and the jitter is 1 minute, then the actual timeout will # be between 3 and 4 minutes. Disabled when the value is 0, defaults to 0. - timeout.reconciliation.jitter: 0 + timeout.reconciliation.jitter: "0" # cluster.inClusterEnabled indicates whether to allow in-cluster server address. This is enabled by default. cluster.inClusterEnabled: "true" # The maximum number of pod logs to render in UI. If the application has more than this number of pods, the logs will not be rendered. # This is to prevent the UI from becoming unresponsive when rendering a large number of logs. Default is 10. - server.maxPodLogsToRender: 10 + server.maxPodLogsToRender: "10" # Application pod logs RBAC enforcement enables control over who can and who can't view application pod logs. # When you enable the switch, pod logs will be visible only to admin role by default. Other roles/users will not be able to view them via cli and UI. @@ -425,7 +432,7 @@ data: name: some-cluster server: https://some-cluster # The maximum size of the payload that can be sent to the webhook server. - webhook.maxPayloadSizeMB: 1024 + webhook.maxPayloadSizeMB: "50" - # application.sync.impersonation.enabled indicates whether the application sync can be decoupled from control plane service account using impersonation. + # application.sync.impersonation.enabled enables application sync to use a custom service account, via impersonation. This allows decoupling sync from control-plane service account. application.sync.impersonation.enabled: "false" diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index b97ba1605a4c0..72136ae03d072 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -9,6 +9,9 @@ data: # Repo server address. (default "argocd-repo-server:8081") repo.server: "argocd-repo-server:8081" + # Commit server address. (default "argocd-commit-server:8086") + commit.server: "argocd-commit-server:8086" + # Redis server hostname and port (e.g. argocd-redis:6379) redis.server: "argocd-redis:6379" # Enable compression for data sent to Redis with the required compression algorithm. (default 'gzip') @@ -16,6 +19,9 @@ data: # Redis database redis.db: + # Enables the alpha "manifest hydrator" feature. (default "false") + hydrator.enabled: "false" + # Open-Telemetry collector address: (e.g. "otel-collector:4317") otlp.address: "" # Open-Telemetry collector insecure: (e.g. "true") @@ -47,8 +53,13 @@ data: controller.log.level: "info" # Prometheus metrics cache expiration (disabled by default. e.g. 24h0m0s) controller.metrics.cache.expiration: "24h0m0s" - # Specifies timeout between application self heal attempts (default 5) - controller.self.heal.timeout.seconds: "5" + # Specifies exponential backoff timeout parameters between application self heal attempts + controller.self.heal.timeout.seconds: "2" + controller.self.heal.backoff.factor: "3" + controller.self.heal.backoff.cap.seconds: "300" + # Specifies a sync timeout for applications. "0" means no timeout (default "0") + controller.sync.timeout.seconds: "0" + # Cache expiration for app state (default 1h0m0s) controller.app.state.cache.expiration: "1h0m0s" # Specifies if resource health should be persisted in app CRD (default true) @@ -124,8 +135,8 @@ data: server.tls.minversion: "1.2" # The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3") server.tls.maxversion: "1.3" - # The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384") - server.tls.ciphers: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384" + # The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") + server.tls.ciphers: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" # Cache expiration for cluster/repo connection status (default 1h0m0s) server.connection.status.cache.expiration: "1h0m0s" # Cache expiration for OIDC state (default 3m0s) @@ -158,8 +169,8 @@ data: reposerver.tls.minversion: "1.2" # The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3") reposerver.tls.maxversion: "1.3" - # The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384") - reposerver.tls.ciphers: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384" + # The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") + reposerver.tls.ciphers: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" # Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data (default 24h0m0s) reposerver.repo.cache.expiration: "24h0m0s" # Cache expiration default (default 24h0m0s) @@ -171,6 +182,8 @@ data: reposerver.max.combined.directory.manifests.size: '10M' # Paths to be excluded from the tarball streamed to plugins. Separate with ; reposerver.plugin.tar.exclusions: "" + # Enable the repo server to use the 'argocd.argoproj.io/manifest-generate-paths' annotation to guide manifest generation. + reposerver.plugin.use.manifest.generate.paths: "false" # Allow repositories to contain symlinks that leave the boundaries of the repository. # Changing this to "true" will not allow _all_ out-of-bounds symlinks. Those will still be blocked for things like values # files in Helm charts. But symlinks which are not explicitly blocked by other checks will be allowed. @@ -188,6 +201,15 @@ data: # Include hidden directories from Git reposerver.include.hidden.directories: "false" + ## Commit-server properties + # Listen on given address for incoming connections (default "0.0.0.0") + commitserver.listen.address: "0.0.0.0" + # Set the logging format. One of: text|json (default "text") + commitserver.log.format: "text" + # Set the logging level. One of: debug|info|warn|error (default "info") + commitserver.log.level: "info" + # Listen on given address for metrics (default "0.0.0.0") + commitserver.metrics.listen.address: "0.0.0.0" # Set the logging format. One of: text|json (default "text") dexserver.log.format: "text" @@ -239,6 +261,10 @@ data: applicationsetcontroller.enable.scm.providers: "false" # Number of webhook requests processed concurrently (default 50) applicationsetcontroller.webhook.parallelism.limit: "50" + # Override the default requeue time for the controller. (default 3m) + applicationsetcontroller.requeue.after: "3m" + # Enable strict mode for tokenRef in ApplicationSet resources. When enabled, the referenced secret must have a label `argocd.argoproj.io/secret-type` with value `scm-creds`. + applicationsetcontroller.enable.tokenref.strict.mode: "false" ## Argo CD Notifications Controller Properties # Set the logging level. One of: debug|info|warn|error (default "info") diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index d37c514493d37..b38635feb85e0 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -113,6 +113,10 @@ spec: # If set to `true` then the plugin receives repository files with original file mode. Dangerous since the repository # might have executable files. Set to true only if you trust the CMP plugin authors. preserveFileMode: false + + # If set to `true` then the plugin can retrieve git credentials from the reposerver during generate. Plugin authors + # should ensure these credentials are appropriately protected during execution + provideGitCreds: false ``` !!! note @@ -359,6 +363,16 @@ You can set it one of three ways: For option 1, the flag can be repeated multiple times. For option 2 and 3, you can specify multiple globs by separating them with semicolons. +## Application manifests generation using argocd.argoproj.io/manifest-generate-paths + +To enhance the application manifests generation process, you can enable the use of the `argocd.argoproj.io/manifest-generate-paths` annotation. When this flag is enabled, the resources specified by this annotation will be passed to the CMP server for generating application manifests, rather than sending the entire repository. This can be particularly useful for monorepos. + +You can set it one of three ways: + +1. The `--plugin-use-manifest-generate-paths` argument on the repo server. +2. The `reposerver.plugin.use.manifest.generate.paths` key if you are using `argocd-cmd-params-cm` +3. Directly setting `ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS` environment variable on the repo server to `true`. + ## Migrating from argocd-cm plugins Installing plugins by modifying the argocd-cm ConfigMap is deprecated as of v2.4 and has been completely removed starting in v2.8. @@ -493,3 +507,36 @@ spec: args: ["sample args"] preserveFileMode: true ``` + +##### Provide Git Credentials + +By default, the config management plugin is responsible for providing its own credentials to additional Git repositories +that may need to be accessed during manifest generation. The reposerver has these credentials available in its git creds +store. When credential sharing is allowed, the git credentials used by the reposerver to clone the repository contents +are shared for the lifetime of the execution of the config management plugin, utilizing git's `ASKPASS` method to make a +call from the config management sidecar container to the reposerver to retrieve the initialized git credentials. + +Utilizing `ASKPASS` means that credentials are not proactively shared, but rather only provided when an operation requires +them. + +To allow the plugin to access the reposerver git credentials, you can set `provideGitCreds` to `true` in the plugin spec: + +!!! warning + Make sure you trust the plugin you are using. If you set `provideGitCreds` to `true` then the plugin will receive + credentials used to clone the source Git repository. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ConfigManagementPlugin +metadata: + name: pluginName +spec: + init: + command: ["sample command"] + args: ["sample args"] + generate: + command: ["sample command"] + args: ["sample args"] + provideGitCreds: true +``` + diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index d509d1e40b29d..d3b93d27c1601 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -567,6 +567,8 @@ execProviderConfig: } apiVersion: string installHint: string +# Proxy URL for the kubernetes client to use when connecting to the cluster api server +proxyUrl: string # Transport layer security configuration settings tlsClientConfig: # Base64 encoded PEM-encoded bytes (typically read from a client certificate file). @@ -581,6 +583,8 @@ tlsClientConfig: # certificates against. If ServerName is empty, the hostname used to contact the # server is used. serverName: string +# Disable automatic compression for requests to the cluster +disableCompression: boolean ``` Note that if you specify a command to run under `execProviderConfig`, that command must be available in the Argo CD image. See [BYOI (Build Your Own Image)](custom_tools.md#byoi-build-your-own-image). @@ -621,8 +625,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: "mycluster.example.com" - server: "https://mycluster.example.com" + name: "eks-cluster-name-for-argo" + server: "https://xxxyyyzzz.xyz.some-region.eks.amazonaws.com" config: | { "awsAuthConfig": { @@ -636,19 +640,48 @@ stringData: } ``` -Note that you should have IRSA enabled on your EKS cluster, create an appropriate IAM role which allows it to assume -other IAM roles (whichever `roleARN`s that Argo CD needs to assume) and have an assume role policy which allows -the argocd-application-controller and argocd-server pods to assume said role via OIDC. +This setup requires: -Example trust relationship config for `:role/`, which -is required for Argo CD to perform actions via IAM. Ensure that the cluster has an [IAM OIDC provider configured](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) -for it. +1. [IRSA enabled](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) on your Argo CD EKS cluster +2. An IAM role ("management role") for your Argo CD EKS cluster that has an appropriate trust policy and permission policies (see below) +3. A role created for each cluster being added to Argo CD that is assumable by the Argo CD management role +4. An [Access Entry](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html) within each EKS cluster added to Argo CD that gives the cluster's role (from point 3) RBAC permissions +to perform actions within the cluster + - Or, alternatively, an entry within the `aws-auth` ConfigMap within the cluster added to Argo CD ([depreciated by EKS](https://docs.aws.amazon.com/eks/latest/userguide/auth-configmap.html)) + +#### Argo CD Management Role + +The role created for Argo CD (the "management role") will need to have a trust policy suitable for assumption by certain +Argo CD Service Accounts *and by itself*. + +The service accounts that need to assume this role are: + +- `argocd-application-controller`, +- `argocd-applicationset-controller` +- `argocd-server` + +If we create role `arn:aws:iam:::role/` for this purpose, the following +is an example trust policy suitable for this need. Ensure that the Argo CD cluster has an [IAM OIDC provider configured](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). ```json { "Version": "2012-10-17", "Statement": [ { + "Sid": "ExplicitSelfRoleAssumption", + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Action": "sts:AssumeRole", + "Condition": { + "ArnLike": { + "aws:PrincipalArn": "arn:aws:iam:::role/" + } + } + }, + { + "Sid": "ServiceAccountRoleAssumption", "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE" @@ -656,7 +689,11 @@ for it. "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { - "oidc.eks..amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": ["system:serviceaccount:argocd:argocd-application-controller", "system:serviceaccount:argocd:argocd-server"], + "oidc.eks..amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": [ + "system:serviceaccount:argocd:argocd-application-controller", + "system:serviceaccount:argocd:argocd-applicationset-controller", + "system:serviceaccount:argocd:argocd-server" + ], "oidc.eks..amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com" } } @@ -665,27 +702,14 @@ for it. } ``` -The Argo CD management role also needs to be allowed to assume other roles, in this case we want it to assume -`arn:aws:iam:::role/` so that it can manage the cluster mapped to that role. This can be -extended to allow assumption of multiple roles, either as an explicit array of role ARNs or by using `*` where appropriate. +#### Argo CD Service Accounts -```json -{ - "Version" : "2012-10-17", - "Statement" : { - "Effect" : "Allow", - "Action" : "sts:AssumeRole", - "Resource" : [ - ":role/" - ] - } - } -``` +The 3 service accounts need to be modified to include an annotation with the Argo CD management role ARN. -Example service account configs for `argocd-application-controller` and `argocd-server`. +Here's an example service account configurations for `argocd-application-controller`, `argocd-applicationset-controller`, and `argocd-server`. !!! warning - Once the annotations have been set on the service accounts, both the application controller and server pods need to be restarted. +Once the annotations has been set on the service accounts, the application controller and server pods need to be restarted. ```yaml apiVersion: v1 @@ -697,17 +721,110 @@ metadata: --- apiVersion: v1 kind: ServiceAccount +metadata: + annotations: + eks.amazonaws.com/role-arn: ":role/" + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: ":role/" name: argocd-server ``` -In turn, the `roleARN` of each managed cluster needs to be added to each respective cluster's `aws-auth` config map (see +#### IAM Permission Policy + +The Argo CD management role (`arn:aws:iam:::role/` in our example) additionally +needs to be allowed to assume a role for each cluster added to Argo CD. + +If we create a role named `` for an EKS cluster we are adding to Argo CD, we would update the permission +policy of the Argo CD management role to include the following: + +```json +{ + "Version" : "2012-10-17", + "Statement" : { + "Effect" : "Allow", + "Action" : "sts:AssumeRole", + "Resource" : [ + "arn:aws:iam:::role/" + ] + } + } +``` + +This allows the Argo CD management role to assume the cluster role. + +You can add permissions like above to the Argo CD management role for each cluster being managed by Argo CD (assuming you +create a new role per cluster). + +#### Cluster Role Trust Policies + +As stated, each EKS cluster being added to Argo CD should have its own corresponding role. This role should not have any +permission policies. Instead, it will be used to authenticate against the EKS cluster's API. The Argo CD management role +assumes this role, and calls the AWS API to get an auth token via argocd-k8s-auth. That token is used when connecting to +the added cluster's API endpoint. + +If we create role `arn:aws:iam:::role/` for a cluster being added to Argo CD, we should +set its trust policy to give the Argo CD management role permission to assume it. Note that we're granting the Argo CD +management role permission to assume this role above, but we also need to permit that action via the cluster role's +trust policy. + +A suitable trust policy allowing the `IAM_CLUSTER_ROLE` to be assumed by the `ARGO_CD_MANAGEMENT_IAM_ROLE_NAME` role looks like this: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam:::role/" + }, + "Action": "sts:AssumeRole" + } + ] +} +``` + +#### Access Entries + +Each cluster's role (e.g. `arn:aws:iam:::role/`) has no permission policy. Instead, we +associate that role with an EKS permission policy, which grants that role the ability to generate authentication tokens +to the cluster's API. This EKS permission policy decides what RBAC permissions are granted in that process. + +An [access entry](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html) (and the policy associated to the role) can be created using the following commands: + +```bash +# For each cluster being added to Argo CD +aws eks create-access-entry \ + --cluster-name my-eks-cluster-name \ + --principal-arn arn:aws:iam:::role/ \ + --type STANDARD \ + --kubernetes-groups [] # No groups needed + +aws eks associate-access-policy \ + --cluster-name my-eks-cluster-name \ + --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy \ + --access-scope type=cluster \ + --principal-arn arn:aws:iam:::role/ +``` + +The above role is granted cluster admin permissions via `AmazonEKSClusterAdminPolicy`. The Argo CD management role that +assume this role is therefore granted the same cluster admin permissions when it generates an API token when adding the +associated EKS cluster. + +**AWS Auth (Depreciated)** + +Instead of using Access Entries, you may need to use the depreciated `aws-auth`. + +If so, the `roleARN` of each managed cluster needs to be added to each respective cluster's `aws-auth` config map (see [Enabling IAM principal access to your cluster](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html)), as well as having an assume role policy which allows it to be assumed by the Argo CD pod role. -Example assume role policy for a cluster which is managed by Argo CD: +An example assume role policy for a cluster which is managed by Argo CD: ```json { @@ -734,10 +851,12 @@ data: mapRoles: | - "groups": - "" - "rolearn": ":role/" - "username": "" + "rolearn": "arn:aws:iam:::role/" + "username": "arn:aws:iam:::role/" ``` +Use the role ARN for both `rolearn` and `username`. + #### Alternative EKS Authentication Methods In some scenarios it may not be possible to use IRSA, such as when the Argo CD cluster is running on a different cloud provider's platform. In this case, there are two options: @@ -787,7 +906,7 @@ the role can be appended to the `args` section like so: ```yaml ... - "args": ["aws", "--cluster-name", "my-eks-cluster", "--roleARN", "arn:aws:iam:::role/"], + "args": ["aws", "--cluster-name", "my-eks-cluster", "--role-arn", "arn:aws:iam:::role/"], ... ``` This construct can be used in conjunction with something like the External Secrets Operator to avoid storing the keys in @@ -1106,6 +1225,14 @@ Notes: * Invalid globs result in the whole rule being ignored. * If you add a rule that matches existing resources, these will appear in the interface as `OutOfSync`. +## Mask sensitive Annotations on Secrets + +An optional comma-separated list of `metadata.annotations` keys can be configured with `resource.sensitive.mask.annotations` to mask their values in UI/CLI on Secrets. + +```yaml + resource.sensitive.mask.annotations: openshift.io/token-secret.value, api-key +``` + ## Auto respect RBAC for controller Argocd controller can be restricted from discovering/syncing specific resources using just controller rbac, without having to manually configure resource exclusions. diff --git a/docs/operator-manual/dynamic-cluster-distribution.md b/docs/operator-manual/dynamic-cluster-distribution.md index 9d5d2104a1795..48df5b555005d 100644 --- a/docs/operator-manual/dynamic-cluster-distribution.md +++ b/docs/operator-manual/dynamic-cluster-distribution.md @@ -1,5 +1,9 @@ # Dynamic Cluster Distribution +!!! warning "Alpha Feature (Since v2.9.0)" + This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha) feature. + It may be removed in future releases or modified in backwards-incompatible ways. + *Current Status: [Alpha][1] (Since v2.9.0)* By default, clusters are assigned to shards indefinitely. For users of the default, hash-based sharding algorithm, this @@ -49,5 +53,3 @@ The new sharding mechanism does not monitor the environment variable `ARGOCD_CON In the scenario when the number of Application Controller replicas increases, a new entry is added to the list of mappings in the `argocd-app-controller-shard-cm` ConfigMap and the cluster distribution is triggered to re-distribute the clusters. In the scenario when the number of Application Controller replicas decreases, the mappings in the `argocd-app-controller-shard-cm` ConfigMap are reset and every controller acquires the shard again thus triggering the re-distribution of the clusters. - -[1]: https://github.com/argoproj/argoproj/blob/master/community/feature-status.md diff --git a/docs/operator-manual/feature-maturity.md b/docs/operator-manual/feature-maturity.md new file mode 100644 index 0000000000000..7554c9132efa0 --- /dev/null +++ b/docs/operator-manual/feature-maturity.md @@ -0,0 +1,85 @@ +# Feature Maturity + +Argo CD features may be marked with a certain [status](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md) +to indicate their stability and maturity. These are the statuses of non-stable features in Argo CD: + +!!! danger "Using Alpha/Beta features risks" + + Aplha and Beta features do not guarantee backward compatibility and are subject to breaking changes in the future releases. + It is highly suggested for Argo users not to rely on these features in production environments, especially if you do not have + control over the Argo CD upgrades. + + Furthermore, removal of Alpha features may modify your resources to an unpredictable state after Argo CD is upgraded. + You should make sure to document which features are in use and review the [release notes](./upgrading/overview.md) before upgrading. + +## Overview + +| Feature | Introduced | Status | +| ----------------------------------------- | ---------- | ------ | +| [AppSet Progressive Syncs][2] | v2.6.0 | Alpha | +| [Proxy Extensions][3] | v2.7.0 | Alpha | +| [Skip Application Reconcile][4] | v2.7.0 | Alpha | +| [AppSets in any Namespace][5] | v2.8.0 | Beta | +| [Cluster Sharding: round-robin][6] | v2.8.0 | Alpha | +| [Dynamic Cluster Distribution][7] | v2.9.0 | Alpha | +| [Server Side Diff][8] | v2.10.0 | Beta | +| [Cluster Sharding: consistent-hashing][9] | v2.12.0 | Alpha | +| [Service Account Impersonation][10] | v2.13.0 | Alpha | + +## Unstable Configurations + +### Application CRD + +| Feature | Property | Status | +| ------------------------------- | --------------------------------------------------------------------------------------- | ------ | +| [Server Side Diff][8] | `metadata.annotations[argocd.argoproj.io/compare-options]: ServerSideDiff=true` | Beta | +| [Server Side Diff][8] | `metadata.annotations[argocd.argoproj.io/compare-options]: IncludeMutationWebhook=true` | Beta | +| [Skip Application Reconcile][4] | `metadata.annotations[argocd.argoproj.io/skip-reconcile]` | Alpha | + +### AppProject CRD + +| Feature | Property | Status | +| ----------------------------------- | ----------------------------------- | ------ | +| [Service Account Impersonation][10] | `spec.destinationServiceAccounts.*` | Alpha | + +### ApplicationSet CRD + +| Feature | Property | Status | +| ----------------------------- | ---------------------------- | ------ | +| [AppSet Progressive Syncs][2] | `spec.strategy.*` | Alpha | +| [AppSet Progressive Syncs][2] | `status.applicationStatus.*` | Alpha | + +### Configuration + +| Feature | Resource | Property / Variable | Status | +| ----------------------------------------- | --------------------------------------------- | ----------------------------------------------------------- | ------ | +| [AppSets in any Namespace][5] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS` | Beta | +| [AppSets in any Namespace][5] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.allowed.scm.providers` | Beta | +| [AppSets in any Namespace][5] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.enable.scm.providers` | Beta | +| [AppSets in any Namespace][5] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS` | Beta | +| [AppSets in any Namespace][5] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES` | Beta | +| [AppSets in any Namespace][5] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.namespaces` | Beta | +| [Server Side Diff][8] | `ConfigMap/argocd-cmd-params-cm` | `controller.diff.server.side` | Beta | +| [Server Side Diff][8] | `StatefulSet/argocd-application-controller` | `ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF` | Beta | +| [AppSet Progressive Syncs][2] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.enable.progressive.syncs` | Alpha | +| [AppSet Progressive Syncs][2] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS` | Alpha | +| [Proxy Extensions][3] | `ConfigMap/argocd-cmd-params-cm` | `server.enable.proxy.extension` | Alpha | +| [Proxy Extensions][3] | `Deployment/argocd-server` | `ARGOCD_SERVER_ENABLE_PROXY_EXTENSION` | Alpha | +| [Proxy Extensions][3] | `ConfigMap/argocd-cm` | `extension.config` | Alpha | +| [Dynamic Cluster Distribution][7] | `Deployment/argocd-application-controller` | `ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION` | Alpha | +| [Dynamic Cluster Distribution][7] | `Deployment/argocd-application-controller` | `ARGOCD_CONTROLLER_HEARTBEAT_TIME` | Alpha | +| [Cluster Sharding: round-robin][6] | `ConfigMap/argocd-cmd-params-cm` | `controller.sharding.algorithm: round-robin` | Alpha | +| [Cluster Sharding: round-robin][6] | `StatefulSet/argocd-application-controller` | `ARGOCD_CONTROLLER_SHARDING_ALGORITHM=round-robin` | Alpha | +| [Cluster Sharding: consistent-hashing][9] | `ConfigMap/argocd-cmd-params-cm` | `controller.sharding.algorithm: consistent-hashing` | Alpha | +| [Cluster Sharding: consistent-hashing][9] | `StatefulSet/argocd-application-controller` | `ARGOCD_CONTROLLER_SHARDING_ALGORITHM=consistent-hashing` | Alpha | +| [Service Account Impersonation][10] | `ConfigMap/argocd-cm` | `application.sync.impersonation.enabled` | Alpha | + +[2]: applicationset/Progressive-Syncs.md +[3]: ../developer-guide/extensions/proxy-extensions.md +[4]: ../user-guide/skip_reconcile.md +[5]: applicationset/Appset-Any-Namespace.md +[6]: ./high_availability.md#argocd-application-controller +[7]: dynamic-cluster-distribution.md +[8]: ../user-guide/diff-strategies.md#server-side-diff +[9]: ./high_availability.md#argocd-application-controller +[10]: app-sync-using-impersonation.md diff --git a/docs/operator-manual/health.md b/docs/operator-manual/health.md index 107f2f3f92cdb..ffce008b1f192 100644 --- a/docs/operator-manual/health.md +++ b/docs/operator-manual/health.md @@ -98,20 +98,27 @@ data: return hs ``` -In order to prevent duplication of the custom health check for potentially multiple resources, it is also possible to specify a wildcard in the resource kind, and anywhere in the resource group, like this: +In order to prevent duplication of custom health checks for potentially multiple resources, it is also possible to +specify a wildcard in the resource kind, and anywhere in the resource group, like this: ```yaml - resource.customizations.health.ec2.aws.crossplane.io_*: | - ... + resource.customizations: | + ec2.aws.crossplane.io/*: + health.lua: | + ... ``` ```yaml - resource.customizations.health.*.aws.crossplane.io_*: | - ... + # If a key _begins_ with a wildcard, please ensure that the GVK key is quoted. + resource.customizations: | + "*.aws.crossplane.io/*": + health.lua: | + ... ``` !!!important - Please, note that there can be ambiguous resolution of wildcards, see [#16905](https://github.com/argoproj/argo-cd/issues/16905) + Please, note that wildcards are only supported when using the `resource.customizations` key, the `resource.customizations.health._` +style keys do not work since wildcards (`*`) are not supported in Kubernetes configmap keys. The `obj` is a global variable which contains the resource. The script must return an object with status and optional message field. The custom health check might return one of the following health statuses: @@ -121,7 +128,7 @@ The custom health check might return one of the following health statuses: * `Degraded` - the resource is degraded * `Suspended` - the resource is suspended and waiting for some external event to resume (e.g. suspended CronJob or paused Deployment) -By default health typically returns `Progressing` status. +By default, health typically returns a `Progressing` status. NOTE: As a security measure, access to the standard Lua libraries will be disabled by default. Admins can control access by setting `resource.customizations.useOpenLibs._`. In the following example, standard libraries are enabled for health check of `cert-manager.io/Certificate`. @@ -191,7 +198,9 @@ The following resources have Go-based health checks: ## Health Checks An Argo CD App's health is inferred from the health of its immediate child resources (the resources represented in -source control). +source control). The App health will be the worst health of its immediate child sources. The priority of most to least +healthy statuses is: `Healthy`, `Suspended`, `Progressing`, `Missing`, `Degraded`, `Unknown`. So, for example, if an App +has a `Missing` resource and a `Degraded` resource, the App's health will be `Missing`. But the health of a resource is not inherited from child resources - it is calculated using only information about the resource itself. A resource's status field may or may not contain information about the health of a child resource, and @@ -220,3 +229,16 @@ App (healthy) └── CustomResource (healthy) <- This resource's health check needs to be fixed to mark the App as unhealthy └── CustomChildResource (unhealthy) ``` +## Ignoring Child Resource Health Check in Applications + +To ignore the health check of an immediate child resource within an Application, set the annotation `argocd.argoproj.io/ignore-healthcheck` to `true`. For example: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + argocd.argoproj.io/ignore-healthcheck: "true" +``` + +By doing this, the health status of the Deployment will not affect the health of its parent Application. \ No newline at end of file diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index 7808bfd677bfd..98e8a709f8852 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -130,6 +130,15 @@ stringData: count (grouped by k8s api version, the granule of parallelism for list operations). In this case, all resources will be buffered in memory -- no api server request will be blocked by processing. +* `ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING` - environment variable that enables the controller to collect events + for Kubernetes resources and process them in a batch. This is useful when the cluster contains a large number of resources, + and the controller is overwhelmed by the number of events. The default value is `false`, which means that the controller + processes events one by one. + +* `ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING_INTERVAL` - environment variable controlling the interval for processing events in a batch. + The valid value is in the format of Go time duration string, e.g. `1ms`, `1s`, `1m`, `1h`. The default value is `100ms`. + The variable is used only when `ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING` is set to `true`. + * `ARGOCD_APPLICATION_TREE_SHARD_SIZE` - environment variable controlling the max number of resources stored in one Redis key. Splitting application tree into multiple keys helps to reduce the amount of traffic between the controller and Redis. The default value is 0, which means that the application tree is stored in a single Redis key. The reasonable value is 100. @@ -277,6 +286,9 @@ spec: # ... ``` +!!! note + If application manifest generation using the `argocd.argoproj.io/manifest-generate-paths` annotation feature is enabled, only the resources specified by this annotation will be sent to the CMP server for manifest generation, rather than the entire repository. To determine the appropriate resources, a common root path is calculated based on the paths provided in the annotation. The application path serves as the deepest path that can be selected as the root. + ### Application Sync Timeout & Jitter Argo CD has a timeout for application syncs. It will trigger a refresh for each application periodically when the timeout expires. diff --git a/docs/operator-manual/index.md b/docs/operator-manual/index.md index 7264f6c3e550a..eef17b9b26adc 100644 --- a/docs/operator-manual/index.md +++ b/docs/operator-manual/index.md @@ -1,6 +1,6 @@ # Overview -This guide is for administrator and operator wanting to install and configure Argo CD for other developers. +This guide is for administrators and operators wanting to install and configure Argo CD for other developers. !!! note Please make sure you've completed the [getting started guide](../getting_started.md). \ No newline at end of file diff --git a/docs/operator-manual/ingress.md b/docs/operator-manual/ingress.md index 652458c32f093..b3a477252feec 100644 --- a/docs/operator-manual/ingress.md +++ b/docs/operator-manual/ingress.md @@ -415,7 +415,7 @@ apiVersion: v1 kind: Service metadata: annotations: - alb.ingress.kubernetes.io/backend-protocol-version: HTTP2 #This tells AWS to send traffic from the ALB using HTTP2. Can use GRPC as well if you want to leverage GRPC specific features + alb.ingress.kubernetes.io/backend-protocol-version: GRPC # This tells AWS to send traffic from the ALB using GRPC. Plain HTTP2 can be used, but the health checks wont be available because argo currently downgrade non-grpc calls to HTTP1 labels: app: argogrpc name: argogrpc @@ -454,7 +454,7 @@ Once we create this service, we can configure the Ingress to conditionally route - path: / backend: service: - name: argogrpc + name: argogrpc # The grpc service must be placed before the argocd-server for the listening rules to be created in the correct order port: number: 443 pathType: Prefix diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index 02a490998307a..deb6037aab94c 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -11,6 +11,7 @@ Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoin | `argocd_app_condition` | gauge | Report Applications conditions. It contains the conditions currently present in the application status. | | `argocd_app_k8s_request_total` | counter | Number of Kubernetes requests executed during application reconciliation | | `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. | +| `argocd_app_orphaned_resources_count` | gauge | Number of orphaned resources per application. | | `argocd_app_reconcile` | histogram | Application reconciliation performance in seconds. | | `argocd_app_sync_total` | counter | Counter for application sync history | | `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. | @@ -23,6 +24,8 @@ Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoin | `argocd_kubectl_exec_total` | counter | Number of kubectl executions | | `argocd_redis_request_duration` | histogram | Redis requests duration. | | `argocd_redis_request_total` | counter | Number of redis requests executed during application reconciliation | +| `argocd_resource_events_processing` | histogram | Time to process resource events in batch in seconds | +| `argocd_resource_events_processed_in_batch` | gauge | Number of resource events processed in batch | If you use Argo CD with many application and project creation and deletion, the metrics page will keep in cache your application and project's history. @@ -128,6 +131,20 @@ Scraped at the `argocd-repo-server:8084/metrics` endpoint. | `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | | `argocd_repo_pending_request_total` | gauge | Number of pending requests requiring repository lock | +## Commit Server Metrics + +Metrics about the Commit Server. +Scraped at the `argocd-commit-server:8087/metrics` endpoint. + +| Metric | Type | Description | +|---------------------------------------------------------|:---------:|------------------------------------------------------| +| `argocd_commitserver_commit_pending_request_total` | guage | Number of pending commit requests. | +| `argocd_commitserver_git_request_duration_seconds` | histogram | Git requests duration seconds. | +| `argocd_commitserver_git_request_total` | counter | Number of git requests performed by commit server | +| `argocd_commitserver_commit_request_duration_seconds` | histogram | Commit requests duration seconds. | +| `argocd_commitserver_userinfo_request_duration_seconds` | histogram | Userinfo requests duration seconds. | +| `argocd_commitserver_commit_request_total` | counter | Number of commit requests performed by commit server | + ## Prometheus Operator If using Prometheus Operator, the following ServiceMonitor example manifests can be used. diff --git a/docs/operator-manual/notifications/catalog.md b/docs/operator-manual/notifications/catalog.md index f4d88d2cf6aeb..d92561f67aa3f 100644 --- a/docs/operator-manual/notifications/catalog.md +++ b/docs/operator-manual/notifications/catalog.md @@ -57,8 +57,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true }, { @@ -86,8 +86,8 @@ teams: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }, { "name": "Revision", @@ -101,7 +101,7 @@ teams: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Operation Application", @@ -115,7 +115,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#000080' @@ -143,8 +143,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -167,8 +167,8 @@ teams: "value": "{{.app.status.health.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -192,7 +192,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#FF0000' @@ -220,8 +220,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -248,8 +248,8 @@ teams: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -259,7 +259,7 @@ teams: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Operation", @@ -273,7 +273,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#FF0000' @@ -301,8 +301,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -329,8 +329,8 @@ teams: "value": "{{.app.status.operationState.startedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -340,7 +340,7 @@ teams: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Operation", @@ -354,7 +354,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] title: Start syncing application {{.app.metadata.name}}. @@ -386,8 +386,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -410,8 +410,8 @@ teams: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -421,7 +421,7 @@ teams: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Application", @@ -435,7 +435,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] title: Application {{.app.metadata.name}} sync status is 'Unknown' @@ -462,8 +462,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -490,8 +490,8 @@ teams: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -501,7 +501,7 @@ teams: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Operation Details", @@ -515,7 +515,7 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#000080' diff --git a/docs/operator-manual/notifications/services/opsgenie.md b/docs/operator-manual/notifications/services/opsgenie.md index 2cc1ebff62abf..d0caf71c98210 100755 --- a/docs/operator-manual/notifications/services/opsgenie.md +++ b/docs/operator-manual/notifications/services/opsgenie.md @@ -2,28 +2,34 @@ To be able to send notifications with argocd-notifications you have to create an [API Integration](https://docs.opsgenie.com/docs/integrations-overview) inside your [Opsgenie Team](https://docs.opsgenie.com/docs/teams). -1. Login to Opsgenie at https://app.opsgenie.com or https://app.eu.opsgenie.com (if you have an account in the european union) -2. Make sure you already have a team, if not follow this guide https://docs.opsgenie.com/docs/teams -3. Click "Teams" in the Menu on the left -4. Select the team that you want to notify -5. In the teams configuration menu select "Integrations" -6. Click "Add Integration" in the top right corner -7. Select "API" integration -8. Give your integration a name, copy the "API key" and safe it somewhere for later -9. Click "Edit" in the integration settings -10. Make sure the checkbox for "Create and Update Access" is selected, disable the other checkboxes to remove unnecessary permissions -11. Click "Save" at the bottom -12. Click "Turn on integration" in the top right corner -13. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the US/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (European API). -14. You are finished with configuring Opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret. -15. You can find the example `argocd-notifications-cm` configuration at the below. +1. Login to Opsgenie at https://app.opsgenie.com or https://app.eu.opsgenie.com (if you have an account in the European Union). +2. Make sure you already have a team; if not, follow this guide: https://docs.opsgenie.com/docs/teams. +3. Click "Teams" in the Menu on the left. +4. Select the team that you want to notify. +5. In the team's configuration menu, select "Integrations". +6. Click "Add Integration" in the top right corner. +7. Select "API" integration. +8. Give your integration a name, copy the "API key", and save it somewhere for later. +9. Click "Edit" in the integration settings. +10. Make sure the checkbox for "Create and Update Access" is selected; disable the other checkboxes to remove unnecessary permissions. +11. Click "Save" at the bottom. +12. Click "Turn on integration" in the top right corner. +13. Check your browser for the correct server apiURL. If it is "app.opsgenie.com", then use the US/international API URL `api.opsgenie.com`; otherwise, use `api.eu.opsgenie.com` (European API). +14. You are finished with configuring Opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name, and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret. +15. You can find the example `argocd-notifications-cm` configuration below. | **Option** | **Required** | **Type** | **Description** | **Example** | | ------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------- | -------------------------------- | -| `description` | True | `string` | Description field of the alert that is generally used to provide a detailed information about the alert. | `Hello from Argo CD!` | -| `priority` | False | `string` | Priority level of the alert. Possible values are P1, P2, P3, P4 and P5. Default value is P3. | `P1` | +| `description` | True | `string` | Description field of the alert that is generally used to provide detailed information about the alert. | `Hello from Argo CD!` | +| `priority` | False | `string` | Priority level of the alert. Possible values are P1, P2, P3, P4, and P5. Default value is P3. | `P1` | | `alias` | False | `string` | Client-defined identifier of the alert, that is also the key element of Alert De-Duplication. | `Life is too short for no alias` | -| `note` | False | `string` | Additional note that will be added while creating the alert. | `Error from Argo CD!` | +| `note` | False | `string` | Additional note that will be added while creating the alert. | `Error from Argo CD!` | +| `actions` | False | `[]string` | Custom actions that will be available for the alert. | `["Resolve", "Escalate"]` | +| `tags` | False | `[]string` | Tags of the alert. | `["critical", "deployment"]` | +| `visibleTo` | False | `[]alert.Responder` | Teams and users that the alert will become visible to without sending any notification. The `type` field is mandatory for each item, where possible values are `team` and `user`. In addition to the `type` field, either `id` or `name` should be provided for teams, and either `id` or `username` should be given for users. Please note that alerts will be visible to the teams specified within the `responders` field by default, so there is no need to re-specify them in the `visibleTo` field. | `[{Type: "team", Id: "team_id"}, {Type: "user", Id: "user_id"}]` | +| `details` | False | `map[string]string` | Map of key-value pairs to use as custom properties of the alert. | `{"environment": "production", "service": "web"}` | +| `entity` | False | `string` | Entity field of the alert that is generally used to specify which domain the alert is related to. | `web-server` | +| `user` | False | `string` | Display name of the request owner. | `admin_user` | ```yaml apiVersion: v1 @@ -47,6 +53,26 @@ data: priority: P1 alias: {{.app.metadata.name}} note: Error from Argo CD! + actions: + - Restart + - AnExampleAction + tags: + - OverwriteQuietHours + - Critical + visibleTo: + - Id: "{{.app.metadata.responderId}}" + Type: "team" + - Name: "rocket_team" + Type: "team" + - Id: "{{.app.metadata.responderUserId}}" + Type: "user" + - Username: "trinity@opsgenie.com" + Type: "user" + details: + environment: production + service: web + entity: Argo CD Application + user: John Doe trigger.on-a-problem: | - description: Application has a problem. send: @@ -54,11 +80,11 @@ data: when: app.status.health.status == 'Degraded' or app.status.operationState.phase in ['Error', 'Failed'] or app.status.sync.status == 'Unknown' ``` -16. Add annotation in application yaml file to enable notifications for specific Argo CD app. +16. Add annotation in the application YAML file to enable notifications for a specific Argo CD app. ```yaml - apiVersion: argoproj.io/v1alpha1 - kind: Application - metadata: - annotations: - notifications.argoproj.io/subscribe.on-a-problem.opsgenie: +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + notifications.argoproj.io/subscribe.on-a-problem.opsgenie: ``` \ No newline at end of file diff --git a/docs/operator-manual/notifications/services/slack.md b/docs/operator-manual/notifications/services/slack.md index 41bdddd7617c4..e665d7a45b53e 100755 --- a/docs/operator-manual/notifications/services/slack.md +++ b/docs/operator-manual/notifications/services/slack.md @@ -21,11 +21,11 @@ The Slack notification service configuration includes following settings: 1. Create Slack Application using https://api.slack.com/apps?new_app=1 ![1](https://user-images.githubusercontent.com/426437/73604308-4cb0c500-4543-11ea-9092-6ca6bae21cbb.png) -1. Once application is created navigate to `Enter OAuth & Permissions` +1. Once application is created navigate to `OAuth & Permissions` ![2](https://user-images.githubusercontent.com/426437/73604309-4d495b80-4543-11ea-9908-4dea403d3399.png) -1. Click `Permissions` under `Add features and functionality` section and add `chat:write` scope. To use the optional username and icon overrides in the Slack notification service also add the `chat:write.customize` scope. +1. Go to `Scopes` > `Bot Token Scopes` > `Add an OAuth Scope`. Add `chat:write` scope. To use the optional username and icon overrides in the Slack notification service also add the `chat:write.customize` scope. ![3](https://user-images.githubusercontent.com/426437/73604310-4d495b80-4543-11ea-8576-09cd91aea0e5.png) -1. Scroll back to the top, click 'Install App to Workspace' button and confirm the installation. +1. `OAuth & Permission` > `OAuth Tokens for Your Workspace` > `Install to Workspace` ![4](https://user-images.githubusercontent.com/426437/73604311-4d495b80-4543-11ea-9155-9d216b20ec86.png) 1. Once installation is completed copy the OAuth token. ![5](https://user-images.githubusercontent.com/426437/73604312-4d495b80-4543-11ea-832b-a9d9d5e4bc29.png) @@ -117,6 +117,35 @@ template.app-sync-status: | }] ``` +If you want to specify an icon and username for each message, you can specify values for `username` and `icon` in the `slack` field. +For icon you can specify emoji and image URL, just like in the service definition. +If you set `username` and `icon` in template, the values set in template will be used even if values are specified in the service definition. + +```yaml +template.app-sync-status: | + message: | + Application {{.app.metadata.name}} sync is {{.app.status.sync.status}}. + Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. + slack: + username: "testbot" + icon: https://example.com/image.png + attachments: | + [{ + "title": "{{.app.metadata.name}}", + "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#18be52", + "fields": [{ + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + }] + }] +``` + The messages can be aggregated to the slack threads by grouping key which can be specified in a `groupingKey` string field under `slack` field. `groupingKey` is used across each template and works independently on each slack channel. When multiple applications will be updated at the same time or frequently, the messages in slack channel can be easily read by aggregating with git commit hash, application name, etc. diff --git a/docs/operator-manual/notifications/templates.md b/docs/operator-manual/notifications/templates.md index 1d80f20953b24..2cba2ad09e901 100644 --- a/docs/operator-manual/notifications/templates.md +++ b/docs/operator-manual/notifications/templates.md @@ -57,7 +57,7 @@ kind: Secret metadata: name: argocd-notifications-secret stringData: - sampleWebhookToken: secret-token + sampleWebhookToken: secret-token type: Opaque ``` @@ -112,7 +112,7 @@ You can change the timezone to show in notifications as follows. ## Functions -Templates have access to the set of built-in functions: +Templates have access to the set of built-in functions such as the functions of the [Sprig](https://masterminds.github.io/sprig/) package ```yaml apiVersion: v1 diff --git a/docs/operator-manual/notifications/troubleshooting-errors.md b/docs/operator-manual/notifications/troubleshooting-errors.md index ecfcf7151c0ce..db1e2a0db2a38 100644 --- a/docs/operator-manual/notifications/troubleshooting-errors.md +++ b/docs/operator-manual/notifications/troubleshooting-errors.md @@ -27,22 +27,22 @@ metadata: data: service.slack: | token: $slack-token - icon: ":rocket:" + icon: ":rocket:" # <- diff here ``` ### service type 'xxxx' is not supported -You need to check your argocd-notifications controller version. For instance, the teams integration is to support `v1.1.0` and more. +Check the `argocd-notifications` controller version. For example, the Teams integration support started in `v1.1.0`. ## Failed to notify recipient ### notification service 'xxxx' is not supported -You have not defined `xxxx` in `argocd-notifications-cm` or to fail to parse settings. +You have not defined `xxxx` in `argocd-notifications-cm` or parsing failed. ### GitHub.repoURL (\u003cno value\u003e) does not have a / using the configuration -You probably have an Application with [multiple sources](https://argo-cd.readthedocs.io/en/stable/user-guide/multiple_sources/): +Likely caused by an Application with [multiple sources](https://argo-cd.readthedocs.io/en/stable/user-guide/multiple_sources/): ```yaml spec: @@ -53,7 +53,7 @@ spec: targetRevision: "{{branch}}" ``` -So standard notification template won't work (`{{.app.spec.source.repoURL}}`). You should choose a single source instead: +The standard notification template only supports a single source (`{{.app.spec.source.repoURL}}`). Use an index to specify the source in the array: ```yaml template.example: | @@ -61,11 +61,32 @@ template.example: | repoURLPath: "{{ (index .app.spec.sources 0).repoURL }}" ``` +### Error message `POST https://api.github.com/repos/xxxx/yyyy/statuses/: 404 Not Found` + +This case is similar to the previous one, you have multiple sources in the Application manifest. +Default `revisionPath` template `{{.app.status.operationState.syncResult.revision}}` is for an Application with single source. + +Multi-source applications report application statuses in an array: + +```yaml +status: + operationState: + syncResult: + revisions: + - 38cfa22edf9148caabfecb288bfb47dc4352dfc6 + - 38cfa22edf9148caabfecb288bfb47dc4352dfc6 +Quick fix for this is to use `index` function to get the first revision: +```yaml +template.example: | + github: + revisionPath: "{{index .app.status.operationState.syncResult.revisions 0}}" +``` + ## config referenced xxx, but key does not exist in secret - If you are using a custom secret, check that the secret is in the same namespace - You have added the label: `app.kubernetes.io/part-of: argocd` to the secret -- You have tried restarting argocd-notifications controller +- You have tried restarting `argocd-notifications` controller ### Example: Secret: diff --git a/docs/operator-manual/notifications/troubleshooting.md b/docs/operator-manual/notifications/troubleshooting.md index 616cd4b024e82..b128e8244acc9 100644 --- a/docs/operator-manual/notifications/troubleshooting.md +++ b/docs/operator-manual/notifications/troubleshooting.md @@ -65,7 +65,7 @@ configuration. **Example** ```bash kubectl exec -it argocd-notifications-controller- \ - /app/argocd admin notifications trigger get + /usr/local/bin/argocd admin notifications trigger get ``` ## Commands diff --git a/docs/operator-manual/rbac.md b/docs/operator-manual/rbac.md index e85be535bd826..63e71c67f001c 100644 --- a/docs/operator-manual/rbac.md +++ b/docs/operator-manual/rbac.md @@ -122,9 +122,19 @@ To do so, when the action if performed on an application's resource, the `/kind//` but also `delete///kind/`. + + The fact that both of these match will generally not be a problem, because resource kinds generally contain capital + letters, and namespaces cannot contain capital letters. However, it is possible for a resource kind to be lowercase. + So it is better to just always include all the parts of the resource in the pattern (in other words, always use four + slashes). + If we want to grant access to the user to update all resources of an application, but not the application itself: ```csv @@ -135,7 +145,7 @@ If we want to explicitly deny delete of the application, but allow the user to d ```csv p, example-user, applications, delete, default/prod-app, deny -p, example-user, applications, delete/*/Pod/*, default/prod-app, allow +p, example-user, applications, delete/*/Pod/*/*, default/prod-app, allow ``` !!! note @@ -145,7 +155,7 @@ p, example-user, applications, delete/*/Pod/*, default/prod-app, allow ```csv p, example-user, applications, delete, default/prod-app, allow - p, example-user, applications, delete/*/Pod/*, default/prod-app, deny + p, example-user, applications, delete/*/Pod/*/*, default/prod-app, deny ``` #### The `action` action diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index ebf8983a39a97..21394af5c7683 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -11,12 +11,21 @@ When a resource update is ignored, if the resource's [health status](./health.md ## System-Level Configuration +By default, `resource.ignoreResourceUpdatesEnabled` is set to `true`, enabling Argo CD to ignore resource updates. This default setting ensures that Argo CD maintains sustainable performance by reducing unnecessary reconcile operations. If you need to alter this behavior, you can explicitly set `resource.ignoreResourceUpdatesEnabled` to `false` in the `argocd-cm` ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm + namespace: argocd +data: + resource.ignoreResourceUpdatesEnabled: "false" +``` + Argo CD allows ignoring resource updates at a specific JSON path, using [RFC6902 JSON patches](https://tools.ietf.org/html/rfc6902) and [JQ path expressions](https://stedolan.github.io/jq/manual/#path(path_expression)). It can be configured for a specified group and kind in `resource.customizations` key of the `argocd-cm` ConfigMap. -!!!important "Enabling the feature" - The feature is behind a flag. To enable it, set `resource.ignoreResourceUpdatesEnabled` to `"true"` in the `argocd-cm` ConfigMap. - Following is an example of a customization which ignores the `refreshTime` status field of an [`ExternalSecret`](https://external-secrets.io/main/api/externalsecret/) resource: ```yaml diff --git a/docs/operator-manual/resource_actions.md b/docs/operator-manual/resource_actions.md index 0a4ea2cb3936a..8de2984ce0588 100644 --- a/docs/operator-manual/resource_actions.md +++ b/docs/operator-manual/resource_actions.md @@ -80,7 +80,7 @@ The `discovery.lua` script must return a table where the key name represents the Each action name must be represented in the list of `definitions` with an accompanying `action.lua` script to control the resource modifications. The `obj` is a global variable which contains the resource. Each action script returns an optionally modified version of the resource. In this example, we are simply setting `.spec.suspend` to either `true` or `false`. -By default, defining a resource action customization will override any built-in action for this resource kind. If you want to retain the built-in actions, you can set the `mergeBuiltinActions` key to `true`. Your custom actions will have precedence over the built-in actions. +By default, defining a resource action customization will override any built-in action for this resource kind. As of Argo CD version 2.13.0, if you want to retain the built-in actions, you can set the `mergeBuiltinActions` key to `true`. Your custom actions will have precedence over the built-in actions. ```yaml resource.customizations.actions.argoproj.io_Rollout: | mergeBuiltinActions: true @@ -202,4 +202,4 @@ resource.customizations.actions.ConfigMap: | result[1] = impactedResource1 result[2] = impactedResource2 return result -``` \ No newline at end of file +``` diff --git a/docs/operator-manual/resource_actions_builtin.md b/docs/operator-manual/resource_actions_builtin.md index 46230a879a875..9708dcbd1eee6 100644 --- a/docs/operator-manual/resource_actions_builtin.md +++ b/docs/operator-manual/resource_actions_builtin.md @@ -33,6 +33,16 @@ - [notification.toolkit.fluxcd.io/Receiver/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/reconcile/action.lua) - [notification.toolkit.fluxcd.io/Receiver/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/resume/action.lua) - [notification.toolkit.fluxcd.io/Receiver/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/suspend/action.lua) +- [numaflow.numaproj.io/MonoVertex/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/pause/action.lua) +- [numaflow.numaproj.io/MonoVertex/unpause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/unpause/action.lua) +- [numaflow.numaproj.io/Pipeline/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaflow.numaproj.io/Pipeline/actions/pause/action.lua) +- [numaflow.numaproj.io/Pipeline/unpause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaflow.numaproj.io/Pipeline/actions/unpause/action.lua) +- [numaplane.numaproj.io/MonoVertexRollout/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/pause/action.lua) +- [numaplane.numaproj.io/MonoVertexRollout/unpause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/unpause/action.lua) +- [numaplane.numaproj.io/PipelineRollout/allow-data-loss](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/allow-data-loss/action.lua) +- [numaplane.numaproj.io/PipelineRollout/disallow-data-loss](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disallow-data-loss/action.lua) +- [numaplane.numaproj.io/PipelineRollout/pause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/pause/action.lua) +- [numaplane.numaproj.io/PipelineRollout/unpause](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/unpause/action.lua) - [source.toolkit.fluxcd.io/Bucket/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/reconcile/action.lua) - [source.toolkit.fluxcd.io/Bucket/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/resume/action.lua) - [source.toolkit.fluxcd.io/Bucket/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/suspend/action.lua) diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index f0d1a01dbd02d..4eabca77d167f 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -27,6 +27,7 @@ argocd-application-controller [flags] --client-certificate string Path to a client certificate file for TLS --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use + --commit-server string Commit server address. (default "argocd-commit-server:8086") --context string The name of the kubeconfig context to use --default-cache-expiration duration Cache expiration default (default 24h0m0s) --disable-compression If true, opt-out of response compression for all requests to the server @@ -34,6 +35,7 @@ argocd-application-controller [flags] --enable-k8s-event none Enable ArgoCD to use k8s event. For disabling all events, set the value as none. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated) (default [all]) --gloglevel int Set the glog logging level -h, --help help for argocd-application-controller + --hydrator-enabled Feature flag to enable Hydrator. Default ("false") --ignore-normalizer-jq-execution-timeout-seconds duration Set ignore normalizer JQ execution timeout --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster @@ -67,13 +69,17 @@ argocd-application-controller [flags] --repo-server-strict-tls Whether to use strict validation of the TLS cert presented by the repo server --repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60) --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --self-heal-timeout-seconds int Specifies timeout between application self heal attempts (default 5) + --self-heal-backoff-cap-seconds int Specifies max timeout of exponential backoff between application self heal attempts (default 300) + --self-heal-backoff-factor int Specifies factor of exponential timeout between application self heal attempts (default 3) + --self-heal-backoff-timeout-seconds int Specifies initial timeout of exponential backoff between self heal attempts (default 2) + --self-heal-timeout-seconds int Specifies timeout between application self heal attempts --sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). --sentinelmaster string Redis sentinel master group name. (default "master") --server string The address and port of the Kubernetes API server --server-side-diff-enabled Feature flag to enable ServerSide diff. Default ("false") --sharding-method string Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin, consistent-hashing] (default "legacy") --status-processors int Number of application status processors (default 20) + --sync-timeout int Specifies the timeout after which a sync would be terminated. 0 means no timeout (default 0). --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use diff --git a/docs/operator-manual/server-commands/argocd-repo-server.md b/docs/operator-manual/server-commands/argocd-repo-server.md index 3532fc6c30b4a..12e4d34d14028 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -35,6 +35,7 @@ argocd-repo-server [flags] --otlp-insecure OpenTelemetry collector insecure mode (default true) --parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. --plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins. + --plugin-use-manifest-generate-paths Pass the resources described in argocd.argoproj.io/manifest-generate-paths value to the cmpserver to generate the application manifests. --port int Listen on given port for incoming connections (default 8081) --redis string Redis server hostname and port (e.g. argocd-redis:6379). --redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation. diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index 0fe1e2d3ca45e..fe284a5940733 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -55,6 +55,7 @@ argocd-server [flags] --enable-proxy-extension Enable Proxy Extension feature --gloglevel int Set the glog logging level -h, --help help for argocd-server + --hydrator-enabled Feature flag to enable Hydrator. Default ("false") --insecure Run server without TLS --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/operator-manual/upgrading/2.12-2.13.md b/docs/operator-manual/upgrading/2.12-2.13.md index 14b26f22a2d70..9e918cc3deb87 100644 --- a/docs/operator-manual/upgrading/2.12-2.13.md +++ b/docs/operator-manual/upgrading/2.12-2.13.md @@ -1,5 +1,9 @@ # v2.12 to 2.13 +## Upgraded Helm Version + +Note that bundled Helm version has been upgraded from 3.15.2 to 3.15.4. + ## Custom Resource Actions for Flux Resources [`Custom Resource Actions`](../resource_actions.md#Custom-Resource-Actions) have been added for Flux Resources. diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 8616764172988..cae97ac6d0d20 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -262,7 +262,7 @@ data: dex.config: | connectors: # OIDC - - type: OIDC + - type: oidc id: oidc name: OIDC config: @@ -292,7 +292,7 @@ data: dex.config: | connectors: # OIDC - - type: OIDC + - type: oidc id: oidc name: OIDC config: diff --git a/docs/operator-manual/user-management/keycloak.md b/docs/operator-manual/user-management/keycloak.md index 10551321d976a..48eb86f511560 100644 --- a/docs/operator-manual/user-management/keycloak.md +++ b/docs/operator-manual/user-management/keycloak.md @@ -1,14 +1,23 @@ # Keycloak +Keycloak and ArgoCD integration can be configured in two ways with Client authentication and with PKCE. -# Integrating Keycloak and ArgoCD +If you need to authenticate with __argo-cd command line__, you must choose PKCE way. + +* [Keycloak and ArgoCD with Client authentication](#keycloak-and-argocd-with-client-authentication) +* [Keycloak and ArgoCD with PKCE](#keycloak-and-argocd-with-pkce) + +## Keycloak and ArgoCD with Client authentication + +These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak. -These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak. You will create a client within Keycloak and configure ArgoCD to use Keycloak for authentication, using groups set in Keycloak to determine privileges in Argo. -## Creating a new client in Keycloak +### Creating a new client in Keycloak + +First we need to setup a new client. -First we need to setup a new client. Start by logging into your keycloak server, select the realm you want to use (`master` by default) +Start by logging into your keycloak server, select the realm you want to use (`master` by default) and then go to __Clients__ and click the __Create client__ button at the top. ![Keycloak add client](../../assets/keycloak-add-client.png "Keycloak add client") @@ -19,62 +28,97 @@ Enable the __Client authentication__. Configure the client by setting the __Root URL__, __Web origins__, __Admin URL__ to the hostname (https://{hostname}). -Also you can set __Home URL__ to your _/applications_ path and __Valid Post logout redirect URIs__ to "+". +Also you can set __Home URL__ to _/applications_ path and __Valid Post logout redirect URIs__ to "https://{hostname}/applications". The Valid Redirect URIs should be set to https://{hostname}/auth/callback (you can also set the less secure https://{hostname}/* for testing/development purposes, but it's not recommended in production). ![Keycloak configure client](../../assets/keycloak-configure-client.png "Keycloak configure client") -Make sure to click __Save__. There should be a tab called __Credentials__. You can copy the Secret that we'll use in our ArgoCD -configuration. +Make sure to click __Save__. + +There should be a tab called __Credentials__. You can copy the Client Secret that we'll use in our ArgoCD configuration. ![Keycloak client secret](../../assets/keycloak-client-secret.png "Keycloak client secret") -## Configuring the groups claim +### Configuring ArgoCD OIDC -In order for ArgoCD to provide the groups the user is in we need to configure a groups claim that can be included in the authentication token. -To do this we'll start by creating a new __Client Scope__ called _groups_. +Let's start by storing the client secret you generated earlier in the argocd secret _argocd-secret_. -![Keycloak add scope](../../assets/keycloak-add-scope.png "Keycloak add scope") +You can patch it with value copied previously: +```bash +kubectl -n argo-cd patch secret argocd-secret --patch='{"stringData": { "oidc.keycloak.clientSecret": "" }}' +``` -Once you've created the client scope you can now add a Token Mapper which will add the groups claim to the token when the client requests -the groups scope. In the Tab "Mappers", click on "Configure a new mapper" and choose __Group Membership__. -Make sure to set the __Name__ as well as the __Token Claim Name__ to _groups_. Also disable the "Full group path". +Now we can configure the config map and add the oidc configuration to enable our keycloak authentication. +You can use `$ kubectl edit configmap argocd-cm`. -![Keycloak groups mapper](../../assets/keycloak-groups-mapper.png "Keycloak groups mapper") +Your ConfigMap should look like this: -We can now configure the client to provide the _groups_ scope. Go back to the client we've created earlier and go to the Tab "Client Scopes". -Click on "Add client scope", choose the _groups_ scope and add it either to the __Default__ or to the __Optional__ Client Scope. If you put it in the Optional -category you will need to make sure that ArgoCD requests the scope in its OIDC configuration. Since we will always want group information, I recommend -using the Default category. +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm +data: + url: https://argocd.example.com + oidc.config: | + name: Keycloak + issuer: https://keycloak.example.com/realms/master + clientID: argocd + clientSecret: $oidc.keycloak.clientSecret + requestedScopes: ["openid", "profile", "email", "groups"] +``` -![Keycloak client scope](../../assets/keycloak-client-scope.png "Keycloak client scope") +Make sure that: -Create a group called _ArgoCDAdmins_ and have your current user join the group. +- __issuer__ ends with the correct realm (in this example _master_) +- __issuer__ on Keycloak releases older than version 17 the URL must include /auth (in this example /auth/realms/master) +- __clientID__ is set to the Client ID you configured in Keycloak +- __clientSecret__ points to the right key you created in the _argocd-secret_ Secret +- __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes -![Keycloak user group](../../assets/keycloak-user-group.png "Keycloak user group") +## Keycloak and ArgoCD with PKCE -## Configuring ArgoCD OIDC +These instructions will take you through the entire process of getting your ArgoCD application authenticating with Keycloak. -Let's start by storing the client secret you generated earlier in the argocd secret _argocd-secret_. +You will create a client within Keycloak and configure ArgoCD to use Keycloak for authentication, using groups set in Keycloak +to determine privileges in Argo. -1. First you'll need to encode the client secret in base64: `$ echo -n '83083958-8ec6-47b0-a411-a8c55381fbd2' | base64` -2. Then you can edit the secret and add the base64 value to a new key called _oidc.keycloak.clientSecret_ using `$ kubectl edit secret argocd-secret`. - -Your Secret should look something like this: +You will also be able to authenticate using argo-cd command line. -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: argocd-secret -data: - ... - oidc.keycloak.clientSecret: ODMwODM5NTgtOGVjNi00N2IwLWE0MTEtYThjNTUzODFmYmQy - ... -``` +### Creating a new client in Keycloak + +First we need to setup a new client. +Start by logging into your keycloak server, select the realm you want to use (`master` by default) +and then go to __Clients__ and click the __Create client__ button at the top. + +![Keycloak add client](../../assets/keycloak-add-client.png "Keycloak add client") + +Leave default values. + +![Keycloak add client Step 2](../../assets/keycloak-add-client-pkce_2.png "Keycloak add client Step 2") + +Configure the client by setting the __Root URL__, __Web origins__, __Admin URL__ to the hostname (https://{hostname}). + +Also you can set __Home URL__ to _/applications_ path and __Valid Post logout redirect URIs__ to "https://{hostname}/applications". + +The Valid Redirect URIs should be set to: +- http://localhost:8085/auth/callback (needed for argo-cd cli, depends on value from [--sso-port](../../user-guide/commands/argocd_login.md)) +- https://{hostname}/auth/callback +- https://{hostname}/pkce/verify + +![Keycloak configure client](../../assets/keycloak-configure-client-pkce.png "Keycloak configure client") + +Make sure to click __Save__. + +Now go to a tab called __Advanced__, look for parameter named __Proof Key for Code Exchange Code Challenge Method__ and set it to __S256__ + +![Keycloak configure client Step 2](../../assets/keycloak-configure-client-pkce_2.png "Keycloak configure client Step 2") +Make sure to click __Save__. + +### Configuring ArgoCD OIDC Now we can configure the config map and add the oidc configuration to enable our keycloak authentication. You can use `$ kubectl edit configmap argocd-cm`. @@ -91,7 +135,7 @@ data: name: Keycloak issuer: https://keycloak.example.com/realms/master clientID: argocd - clientSecret: $oidc.keycloak.clientSecret + enablePKCEAuthentication: true requestedScopes: ["openid", "profile", "email", "groups"] ``` @@ -100,10 +144,44 @@ Make sure that: - __issuer__ ends with the correct realm (in this example _master_) - __issuer__ on Keycloak releases older than version 17 the URL must include /auth (in this example /auth/realms/master) - __clientID__ is set to the Client ID you configured in Keycloak -- __clientSecret__ points to the right key you created in the _argocd-secret_ Secret +- __enablePKCEAuthentication__ must be set to true to enable correct ArgoCD behaviour with PKCE - __requestedScopes__ contains the _groups_ claim if you didn't add it to the Default scopes -## Configuring ArgoCD Policy +## Configuring the groups claim + +In order for ArgoCD to provide the groups the user is in we need to configure a groups claim that can be included in the authentication token. + +To do this we'll start by creating a new __Client Scope__ called _groups_. + +![Keycloak add scope](../../assets/keycloak-add-scope.png "Keycloak add scope") + +Once you've created the client scope you can now add a Token Mapper which will add the groups claim to the token when the client requests +the groups scope. + +In the Tab "Mappers", click on "Configure a new mapper" and choose __Group Membership__. + +Make sure to set the __Name__ as well as the __Token Claim Name__ to _groups_. Also disable the "Full group path". + +![Keycloak groups mapper](../../assets/keycloak-groups-mapper.png "Keycloak groups mapper") + +We can now configure the client to provide the _groups_ scope. + +Go back to the client we've created earlier and go to the Tab "Client Scopes". + +Click on "Add client scope", choose the _groups_ scope and add it either to the __Default__ or to the __Optional__ Client Scope. + +If you put it in the Optional +category you will need to make sure that ArgoCD requests the scope in its OIDC configuration. +Since we will always want group information, I recommend +using the Default category. + +![Keycloak client scope](../../assets/keycloak-client-scope.png "Keycloak client scope") + +Create a group called _ArgoCDAdmins_ and have your current user join the group. + +![Keycloak user group](../../assets/keycloak-user-group.png "Keycloak user group") + +## Configuring ArgoCD Policy Now that we have an authentication that provides groups we want to apply a policy to these groups. We can modify the _argocd-rbac-cm_ ConfigMap using `$ kubectl edit configmap argocd-rbac-cm`. @@ -126,8 +204,23 @@ You can now login using our new Keycloak OIDC authentication: ![Keycloak ArgoCD login](../../assets/keycloak-login.png "Keycloak ArgoCD login") +If you have used PKCE method, you can also authenticate using command line: +```bash +argocd login argocd.example.com --sso --grpc-web +``` + +argocd cli will start to listen on localhost:8085 and open your web browser to allow you to authenticate with Keycloak. + +Once done, you should see + +![Authentication successful!](../../assets/keycloak-authentication-successful.png "Authentication successful!") + ## Troubleshoot If ArgoCD auth returns 401 or when the login attempt leads to the loop, then restart the argocd-server pod. ``` kubectl rollout restart deployment argocd-server -n argocd ``` + +If you migrate from Client authentification to PKCE, you can have the following error `invalid_request: Missing parameter: code_challenge_method`. + +It could be a redirect issue, try in private browsing or clean browser cookies. diff --git a/docs/operator-manual/webhook.md b/docs/operator-manual/webhook.md index 92789e983d3b3..f57918583e3ba 100644 --- a/docs/operator-manual/webhook.md +++ b/docs/operator-manual/webhook.md @@ -19,7 +19,7 @@ URL configured in the Git provider should use the `/api/webhook` endpoint of you (e.g. `https://argocd.example.com/api/webhook`). If you wish to use a shared secret, input an arbitrary value in the secret. This value will be used when configuring the webhook in the next step. -To prevent DDoS attacks with unauthenticated webhook events (the `/api/webhook` endpoint currently lacks rate limiting protection), it is recommended to limit the payload size. You can achieve this by configuring the `argocd-cm` ConfigMap with the `webhook.maxPayloadSizeMB` attribute. The default value is 1GB. +To prevent DDoS attacks with unauthenticated webhook events (the `/api/webhook` endpoint currently lacks rate limiting protection), it is recommended to limit the payload size. You can achieve this by configuring the `argocd-cm` ConfigMap with the `webhook.maxPayloadSizeMB` attribute. The default value is 50MB. ## Github diff --git a/docs/proposals/decouple-application-sync-user-using-impersonation.md b/docs/proposals/decouple-application-sync-user-using-impersonation.md index 050c8d6b0a635..2f4ebe776ed8f 100644 --- a/docs/proposals/decouple-application-sync-user-using-impersonation.md +++ b/docs/proposals/decouple-application-sync-user-using-impersonation.md @@ -68,9 +68,9 @@ This proposal would allow ArgoCD administrators to manage the cluster permission ### Goals - Applications may only impersonate ServiceAccounts that live in the same namespace as the destination namespace configured in the application.If the service account is created in a different namespace, then the user can provide the service account name in the format `:` . ServiceAccount to be used for syncing each application is determined by the target destination configured in the `AppProject` associated with the `Application`. -- If impersonation feature is enabled, and no service account name is provided in the associated `AppProject`, then the sync operation would fail with an appropriate error message. Users can configure a catch all service account matching all destinations to avoid such sync errors. +- If impersonation feature is enabled, and no service account name is provided in the associated `AppProject`, then the default service account of the destination namespace of the `Application` should be used. - Access restrictions implemented through properties in AppProject (if done) must have the existing behavior. From a security standpoint, any restrictions that were available before switching to a service account based approach should continue to exist even when the impersonation feature is enabled. -- The feature can be enabled/disabled only at the system level. Once enabled/disabled, it is applicable to all ArgoCD `Applications`. +- The feature can be enabled/disabled only at the system level. Once enabled/disabled, it is applicable to all Argo CD `Applications`. ### Non-Goals @@ -82,7 +82,7 @@ As part of this proposal, it would be possible for an ArgoCD Admin to specify a When applications gets synced, based on its destination (target cluster and namespace combination), the `defaultServiceAccount` configured in the `AppProject` will be selected and used for impersonation when executing the kubectl commands for the sync operation. -We would be introducing a new element `destinationServiceAccounts` in `AppProject.spec`. This element is used for the sole purpose of specifying the impersonation configuration. The `defaultServiceAccount` configured for the `AppProject` would be used for the sync operation for a particular destination cluster and namespace. If impersonation feature is enabled and no specific service account is provided in the `AppProject` CR, then the sync operation will fail with an error. Users can configure a catch all service account matching all destinations to avoid such sync errors. +We would be introducing a new element `destinationServiceAccounts` in `AppProject.spec`. This element is used for the sole purpose of specifying the impersonation configuration. The `defaultServiceAccount` configured for the `AppProject` would be used for the sync operation for a particular destination cluster and namespace. If impersonation feature is enabled and no specific service account is provided in the `AppProject` CR, then the `default` service account in the destination namespace would be used for impersonation. ```yaml apiVersion: argoproj.io/v1alpha1 @@ -109,7 +109,7 @@ spec: - server: https://kubernetes.default.svc namespace: guestbook-stage defaultServiceAccount: guestbook-stage-deployer - - server: '* + - server: '*' namespace: '*' defaultServiceAccount: default # catch all service account to be used when all other matches fail. ``` @@ -161,7 +161,10 @@ So that, I can use a generic convention of naming service accounts and avoid ass #### Component: ArgoCD Application Controller -- Provide a configuration in `argocd-cm` which can be modified to enable the Impersonation feature. Set `application.sync.impersonation.enabled: "true"` in the Argo CD ConfigMap. Default value of `application.sync.impersonation.enabled` would be `"false"` and user has to explicitly override it to use this feature. +- Provide a configuration in `argocd-cm` which can be modified to enable the Impersonation feature. Set `applicationcontroller.enable.impersonation: true` in the Argo CD ConfigMap. Default value of `applicationcontroller.enable.impersonation` would be `false` and user has to explicitly override it to use this feature. +- Provide an option to override the Impersonation feature using environment variables. +Set `ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true` in the Application controller environment variables. Default value of the environment variable must be `false` and user has to explicitly set it to `true` to use this feature. +- Provide an option to enable this feature using a command line flag `--enable-impersonation`. This new argument option needs to be added to the Application controller args. - Fix Application Controller `sync.go` to set the Impersonate configuration from the AppProject CR to the `SyncContext` Object (rawConfig and restConfig field, need to understand which config is used for the actual sync and if both configs need to be impersonated.) #### Component: ArgoCD UI diff --git a/docs/proposals/manifest-hydrator.md b/docs/proposals/manifest-hydrator.md new file mode 100644 index 0000000000000..313c92adb78de --- /dev/null +++ b/docs/proposals/manifest-hydrator.md @@ -0,0 +1,538 @@ +--- +title: Manifest Hydrator +authors: + - "@crenshaw-dev" + - "@zachaller" +sponsors: + - TBD # List all interested parties here. +reviewers: + - TBD +approvers: + - TBD + +creation-date: 2024-03-26 +last-updated: 2024-03-26 +--- + +# Manifest Hydrator + +This proposal describes a feature to make manifest hydration (i.e. the "rendered manifest pattern") a first-class feature of Argo CD. + +## Terms + +* dry manifests: DRY or Don't Repeat Yourself - things like Kustomize overlays and Helm charts that produce Kubernetes manifests but are not themselves Kubernetes Manifests +* hydrated manifests: the output from dry manifest tools, i.e. plain Kubernetes manifests + +## Summary + +Manifest hydration tools like Helm and Kustomize are indispensable in GitOps. These tools transform "dry" (Don't Repeat Yourself) sources into plain Kubernetes manifests. The effects of a change to dry sources are not always obvious. So storing only dry sources in git leaves the user with an incomplete and confusing history of their application. This undercuts some of the main benefits of GitOps. + +The "rendered manifests" pattern has emerged as a way to mitigate the downsides of using hydration tools in GitOps. Today, developers use CI tools to automatically hydrate manifests and push to separate branches. They then configure Argo CD to deploy from the hydrated branches. (For more information, see the awesome [blog post](https://akuity.io/blog/the-rendered-manifests-pattern/) and [ArgoCon talk](https://www.youtube.com/watch?v=TonN-369Qfo) by Nicholas Morey.) + +This proposal describes manifest hydration and pushing to git as a first-class feature of Argo CD. + +It offers two modes of operation: push-to-deploy and push-to-stage. In push-to-deploy, hydrated manifests are pushed to the same branch from which Argo CD deploys. In push-to-stage, manifests are pushed to a different branch, and Argo CD relies on some external system to move changes to the deployment branch; this provides an integration point for automated environment promotion systems. + +### Opinions + +This proposal is opinionated. It is based on the belief that, in order to reap the full benefits of GitOps, every change to an application's desired state must originate from a commit to a single GitOps repository. In other words, the full history of the application's desired state must be visible as the commit history on a git repository. + +This requirement is incompatible with tooling which injects nondeterministic configuration into the desired state before it is deployed by the GitOps controller. Examples of nondeterministic external configuration are: + +1) Helm chart dependencies on unpinned chart versions +2) Kustomize remote bases to unpinned git revisions +3) Config tool parameter overrides in the Argo CD Application `spec.source` fields +4) Multiple sources referenced in the same application (knowledge of combination of source versions is held externally to git) + +Injecting nondeterministic configuration makes it impossible to know the complete history of an application by looking at a git branch history. Even if the nondeterministic output is databased (for example, in a hydrated source branch in git), it is impossible for developers to confidently make changes to desired state, because they cannot know ahead of time what other configuration will be injected at deploy time. + +We believe that the problems of injecting external configuration are best solved by asking these two questions: + +1) Does the configuration belong in the developer's interface (i.e. the dry manifests)? +2) Does the configuration need to be mutable at runtime, or only at deploy time? + +If the configuration belongs in the developer's interface, write a tool to push the information to git. Image tags are a good example of such configuration, and the Argo CD Image Updater is a good example of such tooling. + +If the configuration doesn't belong in the developer's interface, and it needs to be updated at runtime, write a controller. The developer shouldn't be expected to maintain configuration which is not an immediate part of their desired state. An example would be an auto-sizing controller which eliminates the need for the developer to manage their own autoscaler config. + +If the configuration doesn't belong in the developer's interface and doesn't need to be updated at runtime (only at deploy time), write a mutating webhook. This is a great option for injecting cluster-specific configuration that the developer doesn't need to directly control. + +With these three options available (git-pushers, controllers, and mutating webhooks), we believe that it is not generally necessary to inject nondeterministic configuration into the manifest hydration process. Instead, we can have a full history of the developer's minimal intent (dry branch) and the full expression of that intent (hydrated branch) completely recorded in a series of commits on a git branch. + +By respecting these limitations, we unlock the ability to manage change promotion/reversion entirely via git. Change lineage is fully represented as a series of dry commit hashes. This makes it possible to write reliable rules around how these hashes are promoted to different environments and how they are reverted (i.e. we can meaningfully say "`prod` may never be more than one dry hash ahead of `test`"). If information about the lineage of an application is scattered among multiple sources, it is difficult or even impossible to meaningfully define rules about how one environment's lineage must relate to that of another environment. + +Being opinionated unlocks the full benefits of GitOps as well as the ability to build a reasonable, reliable preview/promotion/reversion system. + +These opinions will lock out use cases where configuration injection cannot be avoided by writing git-pushers, controllers, or mutating webhooks. We believe that the benefits of making an opinionated system outweigh the costs of compromising those opinions. + +## Motivation + +Many organizations have implemented their own manifest hydration system. By implementing it in Argo CD, we can lower the cost to our users of maintaining those systems, and we can encourage best practices related to the pattern. + +### Goals + +1) Make manifest hydration easy and intuitive for Argo CD users +2) Make it possible to implement a promotion system which relies on the manifest hydration's push-to-stage mode +3) Emphasize maintaining as much of the system's state as possible in git rather than in the Application CR (e.g. source hydrator config values, such as Helm values) +4) Every deployed change must have a corresponding dry commit - i.e. git is always the source of any changes +5) Developers should be able to easily reproduce the manifest hydration process locally, i.e. by running some commands + +#### Hydration Reproducibility + +One goal of this proposal is to make hydration reproducibility easy. Reproducibility brings a couple benefits: easy iteration/debugging and reliable previews. + +##### Easy Iteration/Debugging + +The hydration system should enable developers to easily reproduce the hydration process locally. The developer should be able to run a short series of commands and perform the exact same tasks that Argo CD would take to hydrate their manifests. This allows the developer to verify that Argo CD is behaving as expected and to quickly tweak inputs and see the results. This lets them iterate quickly and improves developer satisfaction and change velocity. + +To provide this experience, the hydrator needs to provide the developer with a few pieces of information: + +1) The input repo URL, path, and commit SHA +2) The hydration tool CLI version(s) (for example, the version of the Helm CLI used for hydration) +3) A series of commands and arguments which the developer can run locally + +Equipped with this information, the developer can perform the exact same steps as Argo CD and be confident that their dry manifest changes will produce the desired output. + +Ensuring that hydration is deterministic assures the developer that the output for a given dry state will be the same next week as it is today. + +###### Avoiding Esoteric Behavior + +We should avoid the developer needing to know Argo CD-specific behavior in order to reproduce hydration. Tools like Helm, Kustimize, etc. have excellent public-facing documentation which the developer should be able to take advantage of without needing to know quirks of Argo CD. + +##### Reliable Previews + +Deterministic hydration output allows Argo CD to produce a reliable change preview when a developer proposes a change to the dry manifests via a PR. + +If output is not deterministic, then a preview generated today might not be valid/correct a week, day, or even hour later. Non-determinism makes it so that developers can't trust that the change they review will be the change actually applied. + +### Non-Goals + +1) Implementing a change promotion system + +## Open Questions + +* The `sourceHydrator` field is mutually exclusive with the `source` and the `sources` field. Should we throw an error if they're both configured, or should we just pick one and ignore the others? +* How will/should this feature relate to the image updater? Is there an opportunity to share code, since both tools involve pushing to git? +* Should we enforce a naming convention for hydrated manifest branches, e.g. `argo/...`? This would make it easier to recommend branch protection rules, for example, only allow pushes to `argo/*` from the argo bot. +* Should we enforce setting a `sourceHydrator.syncSource.path` to something besides `.`? Setting a path makes it easier to add/remove other apps later if desired. + +## Proposal + +Today, Argo CD watches one or more git repositories (configured in the `spec.source` or `spec.sources` field). When a new commit appears, Argo CD updates the desired state by rendering the manifests with the configured manifest hydration tool. If auto-sync is enabled, Argo CD applies the new manifests to the cluster. + +With the introduction of this change, Argo CD will watch two revisions in the same git repository: the first is the "dry source", i.e. the git repo/revision where the un-rendered manifests reside, and the second is the "hydrated source," where the rendered manifests are places and retrieved for syncing to the cluster. + +### New `spec.sourceHydrator` Application Field + +A `sourceHydrator` field will be added to the Argo CD Application spec: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: example +spec: + # The sourceHydrator field is mutually-exclusive with `source` and with `sources`. If this field is configured, we + # should either throw an error or ignore the other two. + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + # This assumes the Application's environments are modeled as directories. + path: environments/e2e + syncSource: + targetBranch: environments/e2e + path: . + # The hydrateTo field is optional. If specified, Argo CD will write hydrated manifests to this branch instead of the + # syncSource.targetBranch. This allows the user to "stage" a hydrated commit before actually deploying the changes + # by merging them into the syncSource branch. A complete change promotion system can be built around this feature. + hydrateTo: + targetBranch: environments/e2e-next + # The path is assumed to be the same as that in syncSource. +``` + +When the Argo CD application controller detects a new commit on the `drySource`, it queue up the hydration process. + +When the application controller detects a new (hydrated) commit on the `syncSource.targetBranch`, it will sync the manifests. + +### Processing a New Dry Commit + +On noticing a new dry commit, Argo CD will first collect all Applications which have the same `drySource` repo and targetRevision. + +Argo CD will then group those sources by the configured `syncSource` targetBranch. + +```go +package hydrator + +import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + +type DrySource struct { + repoURL string + targetRevision string +} + +type SyncSource struct { + targetBranch string +} + +var appGroups map[DrySource]map[SyncSource][]v1alpha1.Application +``` + +Then Argo CD will loop over the apps in each group. For each group, it will run manifest hydration on the configured `drySource.path` and write the result to the configured `syncSource.path`. After looping over all apps in the group and writing all their manifests, it will commit the changes to the configured `syncSource` repoURL and targetBranch (or, if configured, the `hydratedTo` targetBranch). Finally, it will push those changes to git. Then it will repeat this process for the remaining groups. + +The actual push operation should be delegated to the [commit server](./manifest-hydrator/commit-server/README.md). + +To understand how this would work for a simple dev/test/prod setup with two regions, consider this example: + +```yaml +### DEV APPS ### +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: dev-west +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/dev/west + syncSource: + targetBranch: environments/dev + path: west +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: dev-east +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/dev/east + syncSource: + targetBranch: environments/dev + path: east +--- +### TEST APPS ### +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: test-west +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/test/west + syncSource: + targetBranch: environments/test + path: west +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: test-east +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/test/east + syncSource: + targetBranch: environments/prod + path: east +--- +### PROD APPS ### +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: prod-west +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/prod/west + syncSource: + targetBranch: environments/prod + path: west +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: prod-east +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: main + path: environments/prod/east + syncSource: + targetBranch: environments/prod + path: east +--- +``` + +Each commit to the dry branch will result in a commit to up to three branches. Each commit to an environment branch will contain changes for west, east, or both (depending on which is affected). Changes originating from a single dry commit are always grouped into a single hydrated commit. + +### Handling External Values Files + +Since only one source may be used in as the dry source, the multi-source approach to external Helm values files will not work here. Instead, we'll recommend that users use the umbrella chart approach. The main reasons for multi-source as an alternative were convenience (no need to maintain the parent chart) and resolving issues with authentication to dependency charts. We believe the simplification is worth the cost of convenience, and we can address the auth issues as standalone bugs. + +An earlier iteration of this proposal attempted to preserve the multi-source style of external value file inclusion by introducing a "magic" `.argocd-hydrator.yaml` file containing `additionalSources` to reference the Helm chart. In the end, it felt like we were re-implementing Helm's dependencies feature or git submodules. It's better to just rely on one of those existing tools. + +### `.argocd-source.yaml` Support + +The `spec.sourceHydrator.drySource` field contains only three fields: `repoURL`, `targetRevision`, and `path`. + +`spec.source` contains a number of fields for configuring manifest hydration tools (`helm`, `kustomize`, and `directory`). That functionality is still available for `spec.sourceHydrator`. But instead of being configured in the Application CR, those values are set in `.argocd-source.yaml`, an existing "override" mechanism for `spec.source`. By requiring that this configuration be set in `.argocd-source.yaml`, we respect the principle that all changes must be made in git instead of in the Application CR. + +### `spec.destination.namespace` Behavior + +The Application `spec.destination.namespace` field is used to set the `metadata.namespace` field of any namespace resources for which that field is not set in the manifests. + +The hydrator will not inject `metadata.namespace` into the hydrated manifests pushed to git. Instead, Argo CD's behavior of injecting that value immediately before applying to the cluster will continue to be used with the `spec.sourceHydrator.syncSource`. + +### Build Environment Support + +For sources specified in `spec.source` or `spec.sources`, Argo CD [sets certain environment variables](https://argo-cd.readthedocs.io/en/stable/user-guide/build-environment/) before running the manifest hydration tool. + +Some of these environment variables may change independently of the dry source and therefore break the reproducibility of manifest hydration (see the [Opinions](#opinions) section). Therefore, only some environment variables will be populated for the `spec.sourceHydrator` source. + +These environment variables will **not** be set: + +* `ARGOCD_APP_NAME` +* `ARGOCD_APP_NAMESPACE` +* `KUBE_VERSION` +* `KUBE_API_VERSIONS` + +These environment variables will be set because they are commit SHAs and are directly and immutably tied to the dry manifest commit: + +* `ARGOCD_APP_REVISION` +* `ARGOCD_APP_REVISION_SHORT` + +These environment variables will be set because they are inherently tied to the manifest hydrator configuration. If these fields set in `spec.sourceHydrator.drySource` change, we are breaking the connection to the original hydrator configuration anyway. + +* `ARGOCD_APP_SOURCE_PATH` +* `ARGOCD_APP_SOURCE_REPO_URL` +* `ARGOCD_APP_SOURCE_TARGET_REVISION` + +### Support for Helm-Specific Features + +#### App Name / Release Name + +By default, Argo CD's `source` and `sources` fields use the Application's name as the release name when hydrating Helm manifests. + +To centralize the source of truth when using `spec.sourceHydrator`, the default release name will be an empty string, and any different release name should be specified in the `helm.releaseName` field in `.argocd-source.yaml`. + +#### Kube API Versions + +`helm install` supports dynamically reading Kube API versions from the destination cluster to adjust manifest output. `helm template` accepts a list of Kube API versions to simulate the same behavior, and Argo CD's `spec.source` and `spec.sources` fields set those API versions when running `helm template`. + +To centralize the source of truth when using `spec.sourceHydrator`, the Kube API versions will not be populated by default. + +Instead, a new field will be added to the Application's `spec.source.helm` field: + +```yaml +kind: Application +spec: + source: + helm: + apiVersions: + - admissionregistration.k8s.io/v1/MutatingWebhookConfiguration + - admissionregistration.k8s.io/v1/ValidatingWebhookConfiguration + - ... etc. +``` + +That field will also be available in `.argocd-source.yaml`: + +```yaml +helm: + apiVersions: + - admissionregistration.k8s.io/v1/MutatingWebhookConfiguration + - admissionregistration.k8s.io/v1/ValidatingWebhookConfiguration + - ... etc. +``` + +So the appropriate way to set Kube API versions for the source hydrator will be to populate the `.argocd-source.yaml` file. + +#### Hydrated Environment Branches + +Representing the dry manifests of environments as branches has well-documented downsides for developer experience. Specifically, it's toilsome for developers to manage moving changes from one branch to another and avoid drift. + +So environments-as-directories has emerged as the standard for good GitOps practices. Change management across directories in a single branch is much easier to perform and reason about. + +**This proposal does not suggest using branches to represent the dry manifests of environments.** As a matter of fact, this proposal codifies the current best practice of representing the dry manifests as directories in a single branch. + +This proposal recommends using different branches for the _hydrated_ representation of environments only. Using different branches has some benefits: + +1) Intuitive grouping of "changes to ship at once" - for example, if you have app-1-east and app-1-west, it makes sense to merge a single hydrated PR to deploy to both of those apps at once +2) Easy-to-read history of a single environment via the commits history +3) Easy comparison between environments using the SCMs' "compare" interfaces + +In other words, branches make a very nice _read_ interface for _hydrated_ manifests while preserving the best-practice of using _directories_ for the _write_ interface. + +### Commit Metadata + +Each output directory should contain two files: manifest.yaml and README.md. manifest.yaml should contain the plain hydrated manifests. The resources should be sorted by namespace, name, group, and kind (in that order). + +The README will be built using the following template: + +````gotemplate +{{ if eq (len .applications) 1 }} +{{ $appName := (index .applications 0).metadata.name }} +# {{ $appName }} Manifests + +[manifest.yaml](./manifest.yaml) contains the hydrated manifests for the {{ $appName }} application. +{{ end }} +{{ if gt (len .applications) 1 }} +{{ $appName := (index .applications 0).metadata.name }} +# Manifests for {{ len .applications }} Applications + +[manifest.yaml](./manifest.yaml) contains the hydrated manifests for these applications: +{{ range $i, $app := .applications }} +- {{ $app.name }} +{{ end }} +{{ end }} + +These are the details of the most recent change; +* Author: {{ .commitAuthor }} +* Message: {{ .commitMessage }} +* Time: {{ .commitTime }} + +To reproduce the manifest hydration, do the following: + +``` +git clone {{ .repoURL }} +cd {{ .repoName }} +git checkout {{ .dryShortSHA }} +{{ range $i, $command := .commands }} +{{ $command }} +{{ end }} +``` +```` + +This template should be admin-configurable. + +Example output might look like this: + +````markdown +# dev-west Manifests + +[manifest.yaml](./manifest.yaml) contains the hydrated manifests for the dev-west application. + +These are the details of the most recent change; +* Author: Michael Crenshaw +* Message: chore: bumped image tag to v0.0.2 +* Time: 2024-03-27 10:32:04 UTC + +To reproduce the manifest hydration, do the following: + +``` +git clone https://github.com/argoproj/argocd-example-apps +cd argocd-example-apps +git checkout ab2382f +kustomize edit set image my-app:v0.0.2 +kustomize build environments/dev/west +``` +```` + +The hydrator will also write a `hydrator.metadata` file containing a JSON representation of all the values available for README templating. This metadata can be used by external systems (e.g. a PR-based promoter system) to generate contextual information about the hydrated manifest's provenance. + +```json +{ + "commands": ["kustomize edit set image my-app:v0.0.2", "kustomize build ."], + "drySHA": "ab2382f", + "commitAuthor": "Michael Crenshaw ", + "commitMessage": "chore: bump Helm dependency chart to 32.1.12", + "repoURL": "https://github.com/argoproj/argocd-example-apps" +} +``` + +To request a commit to the hydrated branch, the application controller will make a call to the CommitManifests service. + +A single call will bundle all the changes destined for a given targetBranch. + +It's the application controller's job to ensure that the user has write access to the repo before making the call. + +```protobuf +// CommitManifests represents the caller's request for some Kubernetes manifests to be pushed to a git repository. +message CommitManifests { + // repoURL is the URL of the repo we're pushing to. HTTPS or SSH URLs are acceptable. + required string repoURL = 1; + // targetBranch is the name of the branch we're pushing to. + required string targetBranch = 2; + // drySHA is the full SHA256 hash of the "dry commit" from which the manifests were hydrated. + required string drySHA = 3; + // commitAuthor is the name of the author of the dry commit. + required string commitAuthor = 4; + // commitMessage is the short commit message from the dry commit. + required string commitMessage = 5; + // commitTime is the dry commit timestamp. + required string commitTime = 6; + // details holds the information about the actual hydrated manifests. + repeated CommitPathDetails details = 7; +} + +// CommitManifestDetails represents the details about a +message CommitPathDetails { + // path is the path to the directory to which these manifests should be written. + required string path = 1; + // manifests is a list of JSON documents representing the Kubernetes manifests. + repeated string manifests = 2; + // readme is a string which will be written to a README.md alongside the manifest.yaml. + required string readme = 3; +} + +message CommitManifestsResponse { +} +``` + +### Push access + +The hydrator will need to push to the git repository. This will require a secret containing the git credentials. + +Write access will be configured via a Kubernetes secret with the following structure: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + labels: + argocd.argoproj.io/secret-type: repository-write +stringData: + url: 'https://github.com/argoproj/argocd-example-apps' + githubAppID: '123456' + githubInstallationID: '123456' + githubAppPrivateKey: | + ----- +``` + +### Use cases + +#### Use case 1: + +An organization with strong requirements around change auditing might enable manifest hydration in order to generate a full history of changes. + +#### Use case 2: + +### Implementation Details/Notes/Constraints + +### Detailed examples + +### Security Considerations + +This proposal would involve introducing a component capable of pushing to git. + +We'll need to consider what git permissions setup to recommend, what security features we should recommend enabling (e.g. branch protection), etc. + +We'll also need to consider how to store the git push secrets. It's probable that they'll need to be stored in a namespace separate from the other Argo CD components to provide a bit extra protection. + +### Risks and Mitigations + +### Upgrade / Downgrade Strategy + +## Drawbacks + +## Alternatives diff --git a/docs/proposals/manifest-hydrator/README.md b/docs/proposals/manifest-hydrator/README.md new file mode 100644 index 0000000000000..e2af5481e4596 --- /dev/null +++ b/docs/proposals/manifest-hydrator/README.md @@ -0,0 +1,44 @@ +# Argo CD Manifest Hydrator + +Most Argo CD Applications don't directly use plain Kubernetes manifests. They reference a Helm chart or some Kustomize manifests, and then Argo CD transforms those sources into their final form (plain Kubernetes manifests). + +Having Argo CD quietly do this transformation behind the scenes is convenient. But it can make it harder for developers to understand the full state of their application, both current and past. Hydrating (also known as "rendering") the sources and pushing the hydrated manifests to git is a common technique to preserve a full history of an Application's state. + +Argo CD provides first-class tooling to hydrate manifests and push them to git. This document explains how to take advantage of that tooling. + +## Setting up git Push Access + +To use Argo CD's source hydration tooling, you have to grant Argo CD push access to all the repositories for apps using the source hydrator. + +### Security Considerations + +Argo CD stores git push secrets separately from the main Argo CD components and separately from git pull credentials to minimize the possibility of a malicious actor stealing the secrets or hijacking Argo CD components to push malicious changes. + +Pushing hydrated manifests to git can improve security by ensuring that all state changes are stored and auditable. If a malicious actor does manage to produce malicious changes in manifests, those changes will be discoverable in git instead of living only in the live cluster state. + +You should use your SCM's security mechanisms to ensure that Argo CD can only push to the allowed repositories and branches. + +### Adding the Access Credentials + +To set up push access, add a secret to the `argocd-push` namespace with the following format: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: argocd-example-apps + labels: + # Note that this is "repository-push" instead of "repository". The same secret should never be used for both push and pull access. + argocd.argoproj.io/secret-type: repository-push +type: Opaque +stringData: + url: https://github.com/argoproj/argocd-example-apps.git + username: '****' + password: '****' +``` + +Once the secret is available, any Application which has pull access to a given repo will be able to use the source hydration tooling to also push to that repo. + +## Using the `sourceHydrator` Field + +## Migrating from the `source` or `sources` Field diff --git a/docs/proposals/manifest-hydrator/commit-server/README.md b/docs/proposals/manifest-hydrator/commit-server/README.md new file mode 100644 index 0000000000000..b87a6ef0a2445 --- /dev/null +++ b/docs/proposals/manifest-hydrator/commit-server/README.md @@ -0,0 +1,38 @@ +# Commit Server + +The Argo CD Commit Server provides push access to git repositories for hydrated manifests. + +The server exposes a gRPC service which accepts requests to push hydrated manifests to a git repository. This is the interface: + +```protobuf +// CommitManifests represents the caller's request for some Kubernetes manifests to be pushed to a git repository. +message CommitManifests { + // repoURL is the URL of the repo we're pushing to. HTTPS or SSH URLs are acceptable. + required string repoURL = 1; + // targetBranch is the name of the branch we're pushing to. + required string targetBranch = 2; + // drySHA is the full SHA256 hash of the "dry commit" from which the manifests were hydrated. + required string drySHA = 3; + // commitAuthor is the name of the author of the dry commit. + required string commitAuthor = 4; + // commitMessage is the short commit message from the dry commit. + required string commitMessage = 5; + // commitTime is the dry commit timestamp. + required string commitTime = 6; + // details holds the information about the actual hydrated manifests. + repeated CommitPathDetails details = 7; +} + +// CommitManifestDetails represents the details about a +message CommitPathDetails { + // path is the path to the directory to which these manifests should be written. + required string path = 1; + // manifests is a list of JSON documents representing the Kubernetes manifests. + repeated string manifests = 2; + // readme is a string which will be written to a README.md alongside the manifest.yaml. + required string readme = 3; +} + +message CommitManifestsResponse { +} +``` diff --git a/docs/proposals/server-side-pagination.md b/docs/proposals/server-side-pagination.md new file mode 100644 index 0000000000000..61aa84e1cfd5b --- /dev/null +++ b/docs/proposals/server-side-pagination.md @@ -0,0 +1,180 @@ +--- +title: Server Side Pagination for Applications List and Watch APIs +authors: + - "@alexmt" +sponsors: + - "@jessesuen" +reviewers: + - TBD +approvers: + - TBD + +creation-date: 2024-02-14 +last-updated: 2024-02-14 +--- + +# Introduce Server Side Pagination for Applications List and Watch APIs + +Improve Argo CD performance by introducing server side pagination for Applications List and Watch APIs. + +## Open Questions [optional] + +This is where to call out areas of the design that require closure before deciding to implement the +design. + + +## Summary + +The Argo CD API server currently returns all applications in a single response. This can be a performance +bottleneck when there are a large number of applications. This proposal is to introduce server side pagination +for the Applications List and Watch APIs. + +## Motivation + +The main motivation for this proposal it to improve the Argo CD UI responsiveness when there are a large number +of applications. The API server memory usage increases with the number of applications however this is not critical +and can be mitigated by increasing memory limits for the API server deployment. The UI however becames unresponsive +even on a powerful machine when the number of applications increases 2000. The server side pagination will allow +to reduce amount of data returned by the API server and improve the UI responsiveness. + +### Goals + +* Support server side pagination for Applications List and Watch APIs + +* Leverage pagination in the Argo CD UI to improve responsiveness + +* Leverage pagination in the Argo CD CLI to improve performance and reduce load on the API server + +### Non-Goals + +* The API Server is known to use a lot of CPU while applying very large RBAC policies to a large number of applications. + Even with pagination API still need to apply RBAC policies to return "last page" response. So the issueis not addressed by this proposal. + +## Proposal + +**Pagination Cursor** + +It is proposed to add `offset` and `limit` fields for pagination support in Application List API. +The The Watch API is a bit more complex. Both Argo CD user interface and CLI are relying on the Watch API to display real time updates of Argo CD applications. +The Watch API currently supports filtering by a project and an application name. In order to effectively +implement server side pagination for the Watch API we cannot rely on the order of the applications returned by the API server. Instead of +relying on the order it is proposed to rely on the application name and use it as a cursor for pagination. Both the Applications List and Watch +APIs will be extended with the optional `minName` and `maxName` fields. The `minName` field will be used to specify the application name to start from +and the `maxName` field will be used to specify the application name to end at. The fields should be added to the `ApplicationQuery` message +which is used as a request payload for the Applications List and Watch APIs. + +```proto +message ApplicationQuery { + // ... existing fields + // New proto fields for server side pagination + // the application name to start from (app with min name is included in response) + optional string minName = 9; + // the application name to end at (app with max name is included in response) + optional string maxName = 10; + // offset + optional int64 offset = 18; + // limit + optional int64 limit = 19; +} +``` + +**Server Side Filtering** + +In order to support server side pagination the filtering has to be moved to the server side as well. `ApplicationQuery` message needs to be extended with the following fields: + +```proto +message ApplicationQuery { + // ... existing fields + // New proto fields for server side filtering + // the repos filter + repeated string repos = 11; + // the clusters filter + repeated string clusters = 12; + // the namespaces filter + repeated string namespaces = 13; + // the auth sync filter + optional bool autoSyncEnabled = 14; + // the sync status filter + repeated string syncStatuses = 15; + // the health status filter + repeated string healthStatuses = 16; + // search + optional string search = 17; +} +``` + +The Argo CD UI should be updated to populate fields in the List and Watch API requests instead of performing filtering on the client side. + +**Applications Stats** + +The Argo CD UI displays the breakdown of the applications by the sync status, health status etc. Stats numbers are calculated on the client side +and rely on the full list of applications returned by the API server. The server side pagination will break the stats calculation. The proposal is to +intoduce a new `stats` field to the Applications List API response. The field will contain the breakdown of the applications by various statuses. + +```golang +type ApplicationLabelStats struct { + Key string `json:"key" protobuf:"bytes,1,opt,name=key"` + Values []string `json:"values" protobuf:"bytes,2,opt,name=values"` +} + +// ApplicationListStats holds additional information about the list of applications +type ApplicationListStats struct { + Total int64 `json:"total" protobuf:"bytes,1,opt,name=total"` + TotalBySyncStatus map[SyncStatusCode]int64 `json:"totalBySyncStatus,omitempty" protobuf:"bytes,2,opt,name=totalBySyncStatus"` + TotalByHealthStatus map[health.HealthStatusCode]int64 `json:"totalByHealthStatus,omitempty" protobuf:"bytes,3,opt,name=totalByHealthStatus"` + AutoSyncEnabledCount int64 `json:"autoSyncEnabledCount" protobuf:"bytes,4,opt,name=autoSyncEnabledCount"` + Destinations []ApplicationDestination `json:"destinations" protobuf:"bytes,5,opt,name=destinations"` + Namespaces []string `json:"namespaces" protobuf:"bytes,6,opt,name=namespaces"` + Labels []ApplicationLabelStats `json:"labels,omitempty" protobuf:"bytes,7,opt,name=labels"` +} +``` + +The `stats` filter should be populated with information about all applications returned by the API server even when single page is loaded. +The Argo CD UI should be updated to use the stats returned by the API server instead of calculating the stats on the client side. + +**Argo CD CLI** + +The Argo CD CLI should be updated to support server side pagination. The `argocd app list` command should be updated to support `--offset` and `--limit` flags. +If the `--offset` and `--limit` flags are not specified the CLI should use pagination to load all applications in batches of 500 applications. + +### Use cases + +Add a list of detailed use cases this enhancement intends to take care of. + +#### User Server Side Pagination in Argo CD User Interface to improve responsiveness: +As a user, I would like to be able to navigate through the list of applications using the pagination controls. + +#### User Server Side Pagination in Argo CD CLI to reduce load on the API server: +As a user, I would like to use Argo CD CLI to list applications while leveraging the pagination without overloading the API server. + +### Implementation Details/Notes/Constraints [optional] + +**Application Stats** + +**CLI Backward Compatibility** + +Typically we bump minimal supported API version when we introduce a new feature in CLI. In this case I +suggest to support gracefully missing pagination support in CLI. If the API server returns more applications than +specified in `limit` the CLI should assume pagination is not supported and response has full list of applications. +This way the user can downgrade API server without downgrading CLI. + +### Security Considerations + +The proposal does not introduce any new security risks. + +### Risks and Mitigations + +We might need to bump minimal supported API version in CLI to support pagination. The `Implementation Details` section +contains the proposal to avoid doing it. + +### Upgrade / Downgrade Strategy + +The proposal does not introduce any breaking changes. The API server should gracefully handle requests without pagination fields. + +## Drawbacks + +None. + +## Alternatives + +**** \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 26b5dc2049e05..ad1dcf32ff1ea 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,9 @@ -mkdocs==1.3.0 +mkdocs==1.6.1 # Strict mode has been disabled in latest versions of mkdocs-material. # Thus pointing to the older version of mkdocs-material. mkdocs-material==7.1.8 -markdown_include==0.6.0 -pygments==2.15.1 +markdown_include==0.8.1 +pygments==2.18.0 jinja2==3.1.4 -markdown==3.3.7 -pymdown-extensions==10.2.1 \ No newline at end of file +markdown==3.7 +pymdown-extensions==10.12 \ No newline at end of file diff --git a/docs/snyk/index.md b/docs/snyk/index.md index b56336b32e637..586bbaf6a75be 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -13,52 +13,53 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](master/argocd-test.html) | 0 | 0 | 1 | 0 | -| [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 2 | 0 | -| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 1 | -| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 3 | -| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 8 | -| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [go.mod](master/argocd-test.html) | 0 | 0 | 6 | 0 | +| [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 | +| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.12.3 +### v2.13.2 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.12.3/argocd-test.html) | 0 | 0 | 2 | 0 | -| [ui/yarn.lock](v2.12.3/argocd-test.html) | 0 | 0 | 2 | 0 | -| [dex:v2.38.0](v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 6 | -| [haproxy:2.6.17-alpine](v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 3 | -| [redis:7.0.15-alpine](v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.12.3](v2.12.3/quay.io_argoproj_argocd_v2.12.3.html) | 0 | 0 | 8 | 8 | -| [redis:7.0.15-alpine](v2.12.3/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | -| [install.yaml](v2.12.3/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.12.3/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.13.2/argocd-test.html) | 1 | 0 | 7 | 2 | +| [ui/yarn.lock](v2.13.2/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.41.1](v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 | +| [haproxy:2.6.17-alpine](v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.13.2](v2.13.2/quay.io_argoproj_argocd_v2.13.2.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](v2.13.2/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.13.2/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.13.2/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.11.8 +### v2.12.8 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.11.8/argocd-test.html) | 0 | 1 | 3 | 0 | -| [ui/yarn.lock](v2.11.8/argocd-test.html) | 0 | 0 | 2 | 0 | -| [dex:v2.38.0](v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 6 | -| [haproxy:2.6.14-alpine](v2.11.8/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 6 | -| [argocd:v2.11.8](v2.11.8/quay.io_argoproj_argocd_v2.11.8.html) | 0 | 0 | 7 | 16 | -| [redis:7.0.15-alpine](v2.11.8/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | -| [install.yaml](v2.11.8/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.11.8/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.12.8/argocd-test.html) | 1 | 0 | 8 | 2 | +| [ui/yarn.lock](v2.12.8/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.38.0](v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.17-alpine](v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.12.8](v2.12.8/quay.io_argoproj_argocd_v2.12.8.html) | 0 | 0 | 3 | 10 | +| [redis:7.0.15-alpine](v2.12.8/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.12.8/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.12.8/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.10.16 +### v2.11.12 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.10.16/argocd-test.html) | 0 | 1 | 4 | 0 | -| [ui/yarn.lock](v2.10.16/argocd-test.html) | 0 | 0 | 2 | 0 | -| [dex:v2.37.0](v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 1 | 10 | 6 | -| [haproxy:2.6.14-alpine](v2.10.16/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 6 | -| [argocd:v2.10.16](v2.10.16/quay.io_argoproj_argocd_v2.10.16.html) | 0 | 0 | 11 | 20 | -| [redis:7.0.15-alpine](v2.10.16/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | -| [install.yaml](v2.10.16/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.10.16/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.11.12/argocd-test.html) | 1 | 2 | 9 | 2 | +| [ui/yarn.lock](v2.11.12/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.38.0](v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.14-alpine](v2.11.12/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 7 | +| [argocd:v2.11.12](v2.11.12/quay.io_argoproj_argocd_v2.11.12.html) | 0 | 0 | 4 | 20 | +| [redis:7.0.15-alpine](v2.11.12/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.11.12/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.11.12/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index c4531da3f93ef..5c580258abd3b 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

Snyk test report

-

September 15th 2024, 12:20:57 am (UTC+00:00)

+

December 15th 2024, 12:23:55 am (UTC+00:00)

Scanned the following path: @@ -507,7 +507,7 @@

Role or ClusterRole with dangerous permissions

  • - Line number: 22389 + Line number: 22859
  • @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22070 + Line number: 22540
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22157 + Line number: 22627
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22185 + Line number: 22655
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22215 + Line number: 22685
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22233 + Line number: 22703
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22251 + Line number: 22721
  • @@ -829,7 +829,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 22273 + Line number: 22743
  • @@ -881,7 +881,7 @@

    Container could be running with outdated image

  • - Line number: 23345 + Line number: 23833
  • @@ -933,7 +933,7 @@

    Container could be running with outdated image

  • - Line number: 23644 + Line number: 24140
  • @@ -991,7 +991,7 @@

    Container has no CPU limit

  • - Line number: 22882 + Line number: 23352
  • @@ -1049,7 +1049,7 @@

    Container has no CPU limit

  • - Line number: 23151 + Line number: 23635
  • @@ -1107,7 +1107,7 @@

    Container has no CPU limit

  • - Line number: 23105 + Line number: 23589
  • @@ -1165,7 +1165,7 @@

    Container has no CPU limit

  • - Line number: 23211 + Line number: 23697
  • @@ -1223,7 +1223,7 @@

    Container has no CPU limit

  • - Line number: 23316 + Line number: 23804
  • @@ -1281,7 +1281,7 @@

    Container has no CPU limit

  • - Line number: 23340 + Line number: 23828
  • @@ -1339,7 +1339,7 @@

    Container has no CPU limit

  • - Line number: 23644 + Line number: 24140
  • @@ -1397,7 +1397,7 @@

    Container has no CPU limit

  • - Line number: 23397 + Line number: 23887
  • @@ -1455,7 +1455,7 @@

    Container has no CPU limit

  • - Line number: 23729 + Line number: 24227
  • @@ -1513,7 +1513,7 @@

    Container has no CPU limit

  • - Line number: 24119 + Line number: 24619
  • @@ -1565,7 +1565,7 @@

    Container is running with multiple open ports

  • - Line number: 23131 + Line number: 23615
  • @@ -1617,7 +1617,7 @@

    Container is running without liveness probe

  • - Line number: 22882 + Line number: 23352
  • @@ -1669,7 +1669,7 @@

    Container is running without liveness probe

  • - Line number: 23105 + Line number: 23589
  • @@ -1721,7 +1721,7 @@

    Container is running without liveness probe

  • - Line number: 23316 + Line number: 23804
  • @@ -1779,7 +1779,7 @@

    Container is running without memory limit

  • - Line number: 22882 + Line number: 23352
  • @@ -1837,7 +1837,7 @@

    Container is running without memory limit

  • - Line number: 23105 + Line number: 23589
  • @@ -1895,7 +1895,7 @@

    Container is running without memory limit

  • - Line number: 23151 + Line number: 23635
  • @@ -1953,7 +1953,7 @@

    Container is running without memory limit

  • - Line number: 23211 + Line number: 23697
  • @@ -2011,7 +2011,7 @@

    Container is running without memory limit

  • - Line number: 23316 + Line number: 23804
  • @@ -2069,7 +2069,7 @@

    Container is running without memory limit

  • - Line number: 23340 + Line number: 23828
  • @@ -2127,7 +2127,7 @@

    Container is running without memory limit

  • - Line number: 23644 + Line number: 24140
  • @@ -2185,7 +2185,7 @@

    Container is running without memory limit

  • - Line number: 23397 + Line number: 23887
  • @@ -2243,7 +2243,7 @@

    Container is running without memory limit

  • - Line number: 23729 + Line number: 24227
  • @@ -2301,7 +2301,7 @@

    Container is running without memory limit

  • - Line number: 24119 + Line number: 24619
  • @@ -2357,7 +2357,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23029 + Line number: 23511
  • @@ -2413,7 +2413,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23159 + Line number: 23643
  • @@ -2469,7 +2469,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23134 + Line number: 23618
  • @@ -2525,7 +2525,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23250 + Line number: 23736
  • @@ -2581,7 +2581,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23333 + Line number: 23821
  • @@ -2637,7 +2637,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23347 + Line number: 23835
  • @@ -2693,7 +2693,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23651 + Line number: 24147
  • @@ -2749,7 +2749,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 23617 + Line number: 24113
  • @@ -2805,7 +2805,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 24020 + Line number: 24518
  • @@ -2861,7 +2861,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 24320 + Line number: 24846
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 020a13bf79f07..acfee91c3423b 100644 --- a/docs/snyk/master/argocd-iac-namespace-install.html +++ b/docs/snyk/master/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:21:06 am (UTC+00:00)

    +

    December 15th 2024, 12:24:05 am (UTC+00:00)

    Scanned the following path: @@ -835,7 +835,7 @@

    Container could be running with outdated image

  • - Line number: 1138 + Line number: 1156
  • @@ -887,7 +887,7 @@

    Container could be running with outdated image

  • - Line number: 1437 + Line number: 1463
  • @@ -1003,7 +1003,7 @@

    Container has no CPU limit

  • - Line number: 944 + Line number: 958
  • @@ -1061,7 +1061,7 @@

    Container has no CPU limit

  • - Line number: 898 + Line number: 912
  • @@ -1119,7 +1119,7 @@

    Container has no CPU limit

  • - Line number: 1004 + Line number: 1020
  • @@ -1177,7 +1177,7 @@

    Container has no CPU limit

  • - Line number: 1109 + Line number: 1127
  • @@ -1235,7 +1235,7 @@

    Container has no CPU limit

  • - Line number: 1133 + Line number: 1151
  • @@ -1293,7 +1293,7 @@

    Container has no CPU limit

  • - Line number: 1437 + Line number: 1463
  • @@ -1351,7 +1351,7 @@

    Container has no CPU limit

  • - Line number: 1190 + Line number: 1210
  • @@ -1409,7 +1409,7 @@

    Container has no CPU limit

  • - Line number: 1522 + Line number: 1550
  • @@ -1467,7 +1467,7 @@

    Container has no CPU limit

  • - Line number: 1912 + Line number: 1942
  • @@ -1519,7 +1519,7 @@

    Container is running with multiple open ports

  • - Line number: 924 + Line number: 938
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 898 + Line number: 912
  • @@ -1675,7 +1675,7 @@

    Container is running without liveness probe

  • - Line number: 1109 + Line number: 1127
  • @@ -1791,7 +1791,7 @@

    Container is running without memory limit

  • - Line number: 898 + Line number: 912
  • @@ -1849,7 +1849,7 @@

    Container is running without memory limit

  • - Line number: 944 + Line number: 958
  • @@ -1907,7 +1907,7 @@

    Container is running without memory limit

  • - Line number: 1004 + Line number: 1020
  • @@ -1965,7 +1965,7 @@

    Container is running without memory limit

  • - Line number: 1109 + Line number: 1127
  • @@ -2023,7 +2023,7 @@

    Container is running without memory limit

  • - Line number: 1133 + Line number: 1151
  • @@ -2081,7 +2081,7 @@

    Container is running without memory limit

  • - Line number: 1437 + Line number: 1463
  • @@ -2139,7 +2139,7 @@

    Container is running without memory limit

  • - Line number: 1190 + Line number: 1210
  • @@ -2197,7 +2197,7 @@

    Container is running without memory limit

  • - Line number: 1522 + Line number: 1550
  • @@ -2255,7 +2255,7 @@

    Container is running without memory limit

  • - Line number: 1912 + Line number: 1942
  • @@ -2311,7 +2311,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 822 + Line number: 834
  • @@ -2367,7 +2367,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 952 + Line number: 966
  • @@ -2423,7 +2423,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 927 + Line number: 941
  • @@ -2479,7 +2479,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1043 + Line number: 1059
  • @@ -2535,7 +2535,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1126 + Line number: 1144
  • @@ -2591,7 +2591,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1140 + Line number: 1158
  • @@ -2647,7 +2647,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1444 + Line number: 1470
  • @@ -2703,7 +2703,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1410 + Line number: 1436
  • @@ -2759,7 +2759,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1813 + Line number: 1841
  • @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 2113 + Line number: 2169
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 33e1e7ab43d33..6f8eea772af3e 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,20 +456,21 @@

    Snyk test report

    -

    September 15th 2024, 12:18:53 am (UTC+00:00)

    +

    December 15th 2024, 12:21:36 am (UTC+00:00)

    Scanned the following paths:
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/argoproj/argo-cd/get-previous-release/hack/get-previous-release/go.mod (gomodules)
    • /argo-cd/ui/yarn.lock (yarn)
    -
    3 known vulnerabilities
    -
    5 vulnerable dependency paths
    -
    2132 dependencies
    +
    7 known vulnerabilities
    +
    26 vulnerable dependency paths
    +
    2160 dependencies

    @@ -478,7 +479,408 @@

    Snyk test report

    -

    Regular Expression Denial of Service (ReDoS)

    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.1.5 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.1.5 + + github.com/Azure/kubelogin/pkg/internal/token@0.1.5 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.19.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.19.0 + + github.com/hashicorp/go-version@1.6.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.114.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    @@ -489,21 +891,21 @@

    Regular Expression Denial of Service (ReDoS)

    • - Manifest file: /argo-cd ui/yarn.lock + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod
    • - Package Manager: npm + Package Manager: golang
    • - Vulnerable module: + Module: - path-to-regexp + github.com/hashicorp/go-cleanhttp
    • Introduced through: - argo-cd-ui@1.0.0, react-router@4.3.1 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others
    @@ -515,39 +917,122 @@

    Detailed paths

    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 - react-router@4.3.1 + github.com/hashicorp/go-retryablehttp@0.7.7 - path-to-regexp@1.8.0 + github.com/hashicorp/go-cleanhttp@0.5.2
    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.114.0 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 - react-router-dom@4.3.1 + github.com/xanzy/go-gitlab@0.114.0 - react-router@4.3.1 + github.com/hashicorp/go-retryablehttp@0.7.7 - path-to-regexp@1.8.0 + github.com/hashicorp/go-cleanhttp@0.5.2
    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 - argo-ui@1.0.0 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - react-router-dom@4.3.1 + github.com/hashicorp/go-retryablehttp@0.7.7 - react-router@4.3.1 + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd - path-to-regexp@1.8.0 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd + + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 @@ -558,94 +1043,17 @@

      Detailed paths


      -

      Overview

      -

      Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

      -

      Note: - Version 0.1.10 is patched to mitigate this but is also vulnerable if custom regular expressions are used. Due to the existence of this attack vector, the Snyk security team have decided to err on the side of caution in considering the very widely-used v0 branch vulnerable, while the 8.0.0 release has completely eliminated the vulnerable functionality.

      -

      Workaround

      -

      This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

      -

      PoC

      -
      /a${'-a'.repeat(8_000)}/a
      -        
      -

      Details

      -

      Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

      -

      The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

      -

      Let’s take the following regular expression as an example:

      -
      regex = /A(B|C+)+D/
      -        
      -

      This regular expression accomplishes the following:

      -
        -
      • A The string must start with the letter 'A'
      • -
      • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
      • -
      • D Finally, we ensure this section of the string ends with a 'D'
      • -
      -

      The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

      -

      It most cases, it doesn't take very long for a regex engine to find a match:

      -
      $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
      -        0.04s user 0.01s system 95% cpu 0.052 total
      -        
      -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
      -        1.79s user 0.02s system 99% cpu 1.812 total
      -        
      -

      The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

      -

      Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

      -

      Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

      -
        -
      1. CCC
      2. -
      3. CC+C
      4. -
      5. C+CC
      6. -
      7. C+C+C.
      8. -
      -

      The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

      -

      From there, the number of steps the engine must use to validate a string just continues to grow.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      StringNumber of C'sNumber of steps
      ACCCX338
      ACCCCX471
      ACCCCCX5136
      ACCCCCCCCCCCCCCX1465,553
      -

      By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

      -

      Remediation

      -

      Upgrade path-to-regexp to version 8.0.0 or higher.

      -

      References

      - +

      MPL-2.0 license


    -

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +

    MPL-2.0 license

    @@ -662,15 +1070,15 @@

    Concurrent Execution using Shared Resource with Improper Package Manager: golang
  • - Vulnerable module: + Module: - github.com/Azure/azure-sdk-for-go/sdk/azidentity + github.com/gosimple/slug
  • Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.14.0 - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others
  • @@ -684,9 +1092,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/Azure/kubelogin/pkg/token@0.0.20 - - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + github.com/gosimple/slug@1.14.0 @@ -697,46 +1103,17 @@

    Detailed paths


    -

    Overview

    -

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    -

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    -

    Notes:

    -
      -
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      -
    2. -
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      -
    4. -
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      -
    6. -
    7. The vulnerability exists in the following credential types:

      -
    8. -
    -

    ManagedIdentityApplication (.NET)

    -

    ManagedIdentityApplication (Java)

    -

    ManagedIdentityApplication (Node.js)

    -

    Remediation

    -

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Template Injection

    +

    Regular Expression Denial of Service (ReDoS)

    @@ -755,13 +1132,13 @@

    Template Injection

  • Vulnerable module: - dompurify + foundation-sites
  • Introduced through: + argo-cd-ui@1.0.0 and foundation-sites@6.8.1 - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others
  • @@ -775,9 +1152,18 @@

    Detailed paths

    Introduced through: argo-cd-ui@1.0.0 - redoc@2.0.0-rc.64 + foundation-sites@6.8.1 + + + + +
  • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 - dompurify@2.3.6 + foundation-sites@6.8.1 @@ -789,24 +1175,85 @@

    Detailed paths


    Overview

    -

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    -

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    +

    foundation-sites is a responsive front-end framework

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to inefficient backtracking in the regular expressions used in URL forms.

    PoC

    -
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    +        
    https://www.''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
             
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    +

    There is no fixed version for foundation-sites.

    References


  • diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html index 238af83a261bc..b67a18ff82724 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:19:03 am (UTC+00:00)

    +

    December 15th 2024, 12:21:47 am (UTC+00:00)

    Scanned the following paths: @@ -469,8 +469,8 @@

    Snyk test report

    -
    2 known vulnerabilities
    -
    8 vulnerable dependency paths
    +
    23 known vulnerabilities
    +
    44 vulnerable dependency paths
    969 dependencies
    @@ -479,8 +479,1191 @@

    Snyk test report

    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and golang.org/x/crypto/ssh@v0.24.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + golang.org/x/crypto/ssh@v0.24.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc/metadata +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + google.golang.org/grpc/metadata@v1.64.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc/metadata is a package that defines the structure of the metadata supported by the gRPC library

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File in the form of gRPC metadata. If the metadata contains sensitive information an attacker can expose it.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc/metadata to version 1.64.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/vault/api@v1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/vault/api@v1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/serf/coordinate +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/serf/coordinate@v0.10.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/serf/coordinate@v0.10.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex /usr/local/bin/dex +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl/v2 +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/json@v2.13.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/hcl@v1.0.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/hcl@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/hcl/hcl/token@v1.0.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/golang-lru/simplelru +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/golang-lru/simplelru@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/golang-lru/simplelru@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-uuid +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-uuid@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-uuid@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-sockaddr +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-sockaddr@v1.0.6 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-sockaddr@v1.0.6 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-sockaddr/template@v1.0.6 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/strutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/parseutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/awsutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-rootcerts +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-rootcerts@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-rootcerts@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-retryablehttp@v0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-multierror +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-multierror@v1.1.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-multierror@v1.1.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-immutable-radix +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-immutable-radix@v1.3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-immutable-radix@v1.3.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/errwrap +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/errwrap@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/errwrap@v1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -497,14 +1680,14 @@

    Insertion of Sensitive Information into Log File

    Package Manager: golang
  • - Vulnerable module: + Module: - google.golang.org/grpc/metadata + github.com/hashicorp/consul/api
  • Introduced through: - github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0 + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/consul/api@v1.29.1
  • @@ -519,7 +1702,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v4@* - google.golang.org/grpc/metadata@v1.64.0 + github.com/hashicorp/consul/api@v1.29.1 @@ -530,20 +1713,132 @@

    Detailed paths


    -

    Overview

    -

    google.golang.org/grpc/metadata is a package that defines the structure of the metadata supported by the gRPC library

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File in the form of gRPC metadata. If the metadata contains sensitive information an attacker can expose it.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc/metadata to version 1.64.1 or higher.

    -

    References

    - +

    MPL-2.0 license


    + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/gosimple/slug@v1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/gosimple/slug@v1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex /usr/local/bin/dex +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/go-sql-driver/mysql +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.8.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/go-sql-driver/mysql@v1.8.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + +
    @@ -692,6 +1987,9 @@

    References

  • https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2
  • https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0
  • https://openssl-library.org/news/secadv/20240903.txt
  • +
  • http://www.openwall.com/lists/oss-security/2024/09/03/4
  • +
  • https://lists.freebsd.org/archives/freebsd-security/2024-September/000303.html
  • +
  • https://security.netapp.com/advisory/ntap-20240912-0001/

  • @@ -701,6 +1999,169 @@

    References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index cd8be9cb54423..5dc1585aadaa3 100644 --- a/docs/snyk/master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html +++ b/docs/snyk/master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:19:08 am (UTC+00:00)

    +

    December 15th 2024, 12:21:52 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    5 known vulnerabilities
    -
    42 vulnerable dependency paths
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    18 dependencies
    @@ -871,9 +871,43 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

    +

    Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

    +

    The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

    +

    The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

    +

    The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

    +

    While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    Remediation

    Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

    +

    References

    +
    @@ -1091,16 +1125,17 @@

    Remediation

    Upgrade Alpine:3.20 openssl to version 3.3.1-r1 or higher.

    References


    @@ -1288,6 +1323,9 @@

    References

  • https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2
  • https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0
  • https://openssl-library.org/news/secadv/20240903.txt
  • +
  • http://www.openwall.com/lists/oss-security/2024/09/03/4
  • +
  • https://lists.freebsd.org/archives/freebsd-security/2024-September/000303.html
  • +
  • https://security.netapp.com/advisory/ntap-20240912-0001/

  • @@ -1297,6 +1335,202 @@

    References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html index b897f3e78df7d..43f65cad79ae6 100644 --- a/docs/snyk/master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ b/docs/snyk/master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:19:12 am (UTC+00:00)

    +

    December 15th 2024, 12:22:00 am (UTC+00:00)

    Scanned the following paths: @@ -467,8 +467,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index e1b0381827449..7617106e2e62c 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:19:30 am (UTC+00:00)

    +

    December 15th 2024, 12:22:20 am (UTC+00:00)

    Scanned the following paths: @@ -470,9 +470,9 @@

    Snyk test report

    -
    12 known vulnerabilities
    -
    66 vulnerable dependency paths
    -
    2355 dependencies
    +
    20 known vulnerabilities
    +
    100 vulnerable dependency paths
    +
    2380 dependencies
    @@ -481,7 +481,7 @@

    Snyk test report

    -

    CVE-2024-41996

    +

    Insecure Storage of Sensitive Information

    @@ -500,12 +500,12 @@

    CVE-2024-41996

  • Vulnerable module: - openssl/libssl3t64 + pam/libpam0g
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.4 + docker-image|quay.io/argoproj/argocd@latest and pam/libpam0g@1.5.3-5ubuntu5.1
  • @@ -520,7 +520,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -529,9 +529,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - coreutils@9.4-3ubuntu6 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -540,9 +540,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + util-linux@2.39.3-9ubuntu6.1 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -551,9 +551,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - libfido2/libfido2-1@1.14.0-1build3 + apt@2.7.14build2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -562,9 +566,15 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + apt@2.7.14build2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -573,11 +583,17 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - ca-certificates@20240203 + apt@2.7.14build2 - openssl@3.0.13-0ubuntu3.4 + adduser@3.137ubuntu1 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -586,13 +602,24 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + + +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + apt@2.7.14build2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + adduser@3.137ubuntu1 - libssh/libssh-4@0.10.6-2build2 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 @@ -601,15 +628,29 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -618,15 +659,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + apt@2.7.14build2 - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + adduser@3.137ubuntu1 - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.4 + pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -635,7 +674,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl@3.0.13-0ubuntu3.4 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -644,9 +683,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - ca-certificates@20240203 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl@3.0.13-0ubuntu3.4 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -658,28 +697,29 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

    Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    -

    Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

    +

    A vulnerability was found in PAM. The secret information is stored in memory, where the attacker can trigger the victim program to execute by sending characters to its standard input (stdin). As this occurs, the attacker can train the branch predictor to execute an ROP chain speculatively. This flaw could result in leaked passwords, such as those found in /etc/shadow while performing authentications.

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 openssl.

    +

    There is no fixed version for Ubuntu:24.04 pam.

    References


  • -

    Information Exposure

    +

    Improper Authentication

    @@ -698,12 +738,12 @@

    Information Exposure

  • Vulnerable module: - libgcrypt20 + pam/libpam0g
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and libgcrypt20@1.10.3-2build1 + docker-image|quay.io/argoproj/argocd@latest and pam/libpam0g@1.5.3-5ubuntu5.1
  • @@ -718,7 +758,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - libgcrypt20@1.10.3-2build1 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -727,9 +767,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/dirmngr@2.4.4-2ubuntu17 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.10.3-2build1 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -738,9 +778,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpg@2.4.4-2ubuntu17 + util-linux@2.39.3-9ubuntu6.1 - libgcrypt20@1.10.3-2build1 + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -749,9 +789,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpg-agent@2.4.4-2ubuntu17 + apt@2.7.14build2 - libgcrypt20@1.10.3-2build1 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -762,9 +806,13 @@

    Detailed paths

    apt@2.7.14build2 - apt/libapt-pkg6.0t64@2.7.14build2 + adduser@3.137ubuntu1 - libgcrypt20@1.10.3-2build1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -775,9 +823,15 @@

    Detailed paths

    apt@2.7.14build2 - gnupg2/gpgv@2.4.4-2ubuntu17 + adduser@3.137ubuntu1 - libgcrypt20@1.10.3-2build1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1 @@ -786,11 +840,55 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpg@2.4.4-2ubuntu17 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + + +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpgconf@2.4.4-2ubuntu17 + apt@2.7.14build2 - libgcrypt20@1.10.3-2build1 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + pam/libpam-runtime@1.5.3-5ubuntu5.1 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + shadow/login@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 @@ -803,13 +901,29 @@

    Detailed paths

    adduser@3.137ubuntu1 - shadow/passwd@1:4.13+dfsg1-4ubuntu3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest - systemd/libsystemd0@255.4-1ubuntu8.4 + pam/libpam-runtime@1.5.3-5ubuntu5.1 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest - libgcrypt20@1.10.3-2build1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -821,23 +935,22 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. +

    Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    -

    A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

    +

    A flaw was found in pam_access, where certain rules in its configuration file are mistakenly treated as hostnames. This vulnerability allows attackers to trick the system by pretending to be a trusted hostname, gaining unauthorized access. This issue poses a risk for systems that rely on this feature to control who can access certain services or terminals.

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 libgcrypt20.

    +

    There is no fixed version for Ubuntu:24.04 pam.

    References


  • @@ -883,11 +996,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -898,13 +1011,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -915,11 +1028,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -930,13 +1043,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -947,15 +1060,15 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -966,11 +1079,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 @@ -981,7 +1094,7 @@

    Detailed paths

    openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -992,9 +1105,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1005,11 +1118,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1018,7 +1131,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - krb5/krb5-locales@1.20.1-6ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1050,7 +1163,7 @@

    References

    -

    CVE-2024-8096

    +

    LGPL-3.0 license

    @@ -1061,21 +1174,21 @@

    CVE-2024-8096

    • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - curl/libcurl3t64-gnutls + gopkg.in/retry.v1
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 - docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1087,11 +1200,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 + github.com/argoproj/argo-cd/v2@* - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + gopkg.in/retry.v1@v1.0.3 @@ -1102,53 +1213,41 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      When curl is told to use the Certificate Status Request TLS extension, often referred to as OCSP stapling, to verify that the server certificate is valid, it might fail to detect some OCSP problems and instead wrongly consider the response as fine. If the returned status reports another error than 'revoked' (like for example 'unauthorized') it is not treated as a bad certficate.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 curl.

      -

      References

      - +

      LGPL-3.0 license


    -
    -

    Release of Invalid Pointer or Reference

    +
    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - patch + github.com/r3labs/diff
    • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3 + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0
    @@ -1161,9 +1260,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@latest + github.com/argoproj/argo-cd/v2@* - patch@2.7.6-7build3 + github.com/r3labs/diff@v1.1.0 @@ -1174,51 +1273,41 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. - See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 patch.

      -

      References

      - +

      MPL-2.0 license


    -
    -

    Double Free

    +
    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - patch + github.com/hashicorp/go-version
    • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.6.0
    @@ -1231,9 +1320,9 @@

    Detailed paths

    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/hashicorp/go-retryablehttp@v0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/helm/v3 /usr/local/bin/helm +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-multierror +
    • + +
    • Introduced through: + + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + helm.sh/helm/v3@* + + github.com/hashicorp/go-multierror@v1.1.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/gosimple/slug@v1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Release of Invalid Pointer or Reference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + patch@2.7.6-7build3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    Double Free

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + patch@2.7.6-7build3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-41996

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3t64 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.4 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 + + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.4 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Information Exposure

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + libgcrypt20 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and libgcrypt20@1.10.3-2build1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + gnupg2/gpg@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + apt@2.7.14build2 + + apt/libapt-pkg6.0t64@2.7.14build2 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + gnupg2/gpg@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + systemd/libsystemd0@255.4-1ubuntu8.4 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 libgcrypt20.

    +

    References

    + + +
    + +
    @@ -1310,11 +2131,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -1325,13 +2146,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -1342,11 +2163,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1357,13 +2178,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1374,15 +2195,15 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1393,11 +2214,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 @@ -1408,7 +2229,7 @@

    Detailed paths

    openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1419,9 +2240,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1432,11 +2253,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1445,7 +2266,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - krb5/krb5-locales@1.20.1-6ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1518,11 +2339,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -1533,13 +2354,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 @@ -1550,11 +2371,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1565,13 +2386,13 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1582,15 +2403,15 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2 @@ -1601,11 +2422,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 @@ -1616,7 +2437,7 @@

    Detailed paths

    openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1627,9 +2448,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1640,11 +2461,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 @@ -1653,7 +2474,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - krb5/krb5-locales@1.20.1-6ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1971,7 +2792,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - git-lfs@3.4.1-1ubuntu0.1 + git-lfs@3.4.1-1ubuntu0.2 git@1:2.43.0-1ubuntu7.1 diff --git a/docs/snyk/master/redis_7.0.15-alpine.html b/docs/snyk/master/redis_7.0.15-alpine.html index 4048f7704e169..08afe3592a136 100644 --- a/docs/snyk/master/redis_7.0.15-alpine.html +++ b/docs/snyk/master/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:19:34 am (UTC+00:00)

    +

    December 15th 2024, 12:22:25 am (UTC+00:00)

    Scanned the following paths: @@ -467,8 +467,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.10.16/argocd-test.html b/docs/snyk/v2.10.16/argocd-test.html deleted file mode 100644 index 7cd0e72a8b29b..0000000000000 --- a/docs/snyk/v2.10.16/argocd-test.html +++ /dev/null @@ -1,4031 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    September 15th 2024, 12:25:54 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • -
    • /argo-cd/ui/yarn.lock (yarn)
    • -
    -
    - -
    -
    7 known vulnerabilities
    -
    163 vulnerable dependency paths
    -
    2042 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.26.11 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/soheilhy/cmux@0.1.5 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.21.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.46.1 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/apps/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/rbac/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/errors@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/equality@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.59.0 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.59.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.26.11 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.26.11 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/testing@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/resource@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/util/retry@0.26.11 - - k8s.io/apimachinery/pkg/api/errors@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/managedfields@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/portforward@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 - - k8s.io/apimachinery/pkg/api/equality@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/validation@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/diff@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.26.11 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.26.11 - - k8s.io/client-go/tools/reference@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/apps/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.26.11 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.26.11 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 - - k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 - - k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/diff@#b6ec82aedce5 - - k8s.io/kubectl/pkg/cmd/util@0.26.11 - - k8s.io/kubectl/pkg/validation@0.26.11 - - k8s.io/cli-runtime/pkg/resource@0.26.11 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.26.11 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#b6ec82aedce5 - - k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 - - k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 - - k8s.io/api/storage/v1alpha1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Regular Expression Denial of Service (ReDoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - path-to-regexp -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, react-router@4.3.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - argo-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

    -

    Note: - Version 0.1.10 is patched to mitigate this but is also vulnerable if custom regular expressions are used. Due to the existence of this attack vector, the Snyk security team have decided to err on the side of caution in considering the very widely-used v0 branch vulnerable, while the 8.0.0 release has completely eliminated the vulnerable functionality.

    -

    Workaround

    -

    This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

    -

    PoC

    -
    /a${'-a'.repeat(8_000)}/a
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    -

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    -

    Let’s take the following regular expression as an example:

    -
    regex = /A(B|C+)+D/
    -        
    -

    This regular expression accomplishes the following:

    -
      -
    • A The string must start with the letter 'A'
    • -
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • -
    • D Finally, we ensure this section of the string ends with a 'D'
    • -
    -

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    -

    It most cases, it doesn't take very long for a regex engine to find a match:

    -
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    -        0.04s user 0.01s system 95% cpu 0.052 total
    -        
    -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    -        1.79s user 0.02s system 99% cpu 1.812 total
    -        
    -

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    -

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    -

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    -
      -
    1. CCC
    2. -
    3. CC+C
    4. -
    5. C+CC
    6. -
    7. C+C+C.
    8. -
    -

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    -

    From there, the number of steps the engine must use to validate a string just continues to grow.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    -

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    -

    Remediation

    -

    Upgrade path-to-regexp to version 8.0.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Regular Expression Denial of Service (ReDoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/whilp/git-urls -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/whilp/git-urls@1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/whilp/git-urls is a Git URLs parser

    -

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to the usage of an insecure regular expression in scpSyntax. Exploiting this vulnerability is possible when a long input is provided inside the directory path of the git URL.

    -

    Note: - This vulnerability has existed since commit 4a18977c6eecbf4ce0ca1e486e9ba77072ba4395.

    -

    PoC

    -
    
    -        var payload = strings.Repeat("////", 19000000) //payload used, the number can be tweaked to cause 7 second delay
    -        malicious_url := "6en6ar@-:0////" + payload + "\"
    -        begin := time.Now()
    -        //u, err := giturls.ParseScp("remote_username@10.10.0.2:/remote/directory")// normal git url
    -        _, err := giturls.ParseScp(malicious_url)
    -        if err != nil {
    -        fmt.Errorf("[ - ] Error ->" + err.Error())
    -        }
    -        //fmt.Println("[ + ] Url --> " + u.Host)
    -        elapse := time.Since(begin)
    -        fmt.Printf("Function took %s", elapse)
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    -

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    -

    Let’s take the following regular expression as an example:

    -
    regex = /A(B|C+)+D/
    -        
    -

    This regular expression accomplishes the following:

    -
      -
    • A The string must start with the letter 'A'
    • -
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • -
    • D Finally, we ensure this section of the string ends with a 'D'
    • -
    -

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    -

    It most cases, it doesn't take very long for a regex engine to find a match:

    -
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    -        0.04s user 0.01s system 95% cpu 0.052 total
    -        
    -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    -        1.79s user 0.02s system 99% cpu 1.812 total
    -        
    -

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    -

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    -

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    -
      -
    1. CCC
    2. -
    3. CC+C
    4. -
    5. C+CC
    6. -
    7. C+C+C.
    8. -
    -

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    -

    From there, the number of steps the engine must use to validate a string just continues to grow.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    -

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    -

    Remediation

    -

    There is no fixed version for github.com/whilp/git-urls.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/rs/cors -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - github.com/rs/cors@1.9.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    -

    PoC

    -
    
    -        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    -            resps := makeFakeResponses(b.N)
    -            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    -            req.Header.Add(headerOrigin, dummyOrigin)
    -            req.Header.Add(headerACRM, http.MethodGet)
    -            req.Header[headerACRH] = adversarialACRH
    -            handler := Default().Handler(testHandler)
    -        
    -            b.ReportAllocs()
    -            b.ResetTimer()
    -            for i := 0; i < b.N; i++ {
    -                handler.ServeHTTP(resps[i], req)
    -            }
    -        }
    -        
    -        var adversarialACRH []string
    -        
    -        func init() { // populates adversarialACRH
    -            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    -            commas := strings.Repeat(",", n)
    -            res := make([]string, n)
    -            for i := range res {
    -                res[i] = commas
    -            }
    -            adversarialACRH = res
    -        }
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    -

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    -

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    -

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    -

    Two common types of DoS vulnerabilities:

    -
      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      -
    • -
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      -
    • -
    -

    Remediation

    -

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Insertion of Sensitive Information into Log File

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/xanzy/go-gitlab@0.91.1 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/Azure/azure-sdk-for-go/sdk/azidentity -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    -

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    -

    Notes:

    -
      -
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      -
    2. -
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      -
    4. -
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      -
    6. -
    7. The vulnerability exists in the following credential types:

      -
    8. -
    -

    ManagedIdentityApplication (.NET)

    -

    ManagedIdentityApplication (Java)

    -

    ManagedIdentityApplication (Node.js)

    -

    Remediation

    -

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Template Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - dompurify -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - redoc@2.0.0-rc.64 - - dompurify@2.3.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    -

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    -

    PoC

    -
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    -        
    -

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.12.3/argocd-iac-install.html b/docs/snyk/v2.11.12/argocd-iac-install.html similarity index 98% rename from docs/snyk/v2.12.3/argocd-iac-install.html rename to docs/snyk/v2.11.12/argocd-iac-install.html index a5698e85b8c0e..77349b6faacb1 100644 --- a/docs/snyk/v2.12.3/argocd-iac-install.html +++ b/docs/snyk/v2.11.12/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:23:20 am (UTC+00:00)

    +

    December 15th 2024, 12:31:10 am (UTC+00:00)

    Scanned the following path: @@ -507,7 +507,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 21107 + Line number: 21069
  • @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20788 + Line number: 20754
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20875 + Line number: 20839
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20903 + Line number: 20867
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20933 + Line number: 20897
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20951 + Line number: 20915
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20969 + Line number: 20933
  • @@ -829,7 +829,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20991 + Line number: 20955
  • @@ -881,7 +881,7 @@

    Container could be running with outdated image

  • - Line number: 22039 + Line number: 22001
  • @@ -933,7 +933,7 @@

    Container could be running with outdated image

  • - Line number: 22338 + Line number: 22288
  • @@ -991,7 +991,7 @@

    Container has no CPU limit

  • - Line number: 21600 + Line number: 21562
  • @@ -1049,7 +1049,7 @@

    Container has no CPU limit

  • - Line number: 21851 + Line number: 21813
  • @@ -1107,7 +1107,7 @@

    Container has no CPU limit

  • - Line number: 21817 + Line number: 21779
  • @@ -1165,7 +1165,7 @@

    Container has no CPU limit

  • - Line number: 21911 + Line number: 21873
  • @@ -1223,7 +1223,7 @@

    Container has no CPU limit

  • - Line number: 22010 + Line number: 21972
  • @@ -1281,7 +1281,7 @@

    Container has no CPU limit

  • - Line number: 22034 + Line number: 21996
  • @@ -1339,7 +1339,7 @@

    Container has no CPU limit

  • - Line number: 22338 + Line number: 22288
  • @@ -1397,7 +1397,7 @@

    Container has no CPU limit

  • - Line number: 22091 + Line number: 22053
  • @@ -1455,7 +1455,7 @@

    Container has no CPU limit

  • - Line number: 22423 + Line number: 22373
  • @@ -1513,7 +1513,7 @@

    Container has no CPU limit

  • - Line number: 22774 + Line number: 22724
  • @@ -1565,7 +1565,7 @@

    Container is running with multiple open ports

  • - Line number: 21831 + Line number: 21793
  • @@ -1617,7 +1617,7 @@

    Container is running without liveness probe

  • - Line number: 21600 + Line number: 21562
  • @@ -1669,7 +1669,7 @@

    Container is running without liveness probe

  • - Line number: 21817 + Line number: 21779
  • @@ -1721,7 +1721,7 @@

    Container is running without liveness probe

  • - Line number: 22010 + Line number: 21972
  • @@ -1779,7 +1779,7 @@

    Container is running without memory limit

  • - Line number: 21600 + Line number: 21562
  • @@ -1837,7 +1837,7 @@

    Container is running without memory limit

  • - Line number: 21817 + Line number: 21779
  • @@ -1895,7 +1895,7 @@

    Container is running without memory limit

  • - Line number: 21851 + Line number: 21813
  • @@ -1953,7 +1953,7 @@

    Container is running without memory limit

  • - Line number: 21911 + Line number: 21873
  • @@ -2011,7 +2011,7 @@

    Container is running without memory limit

  • - Line number: 22010 + Line number: 21972
  • @@ -2069,7 +2069,7 @@

    Container is running without memory limit

  • - Line number: 22034 + Line number: 21996
  • @@ -2127,7 +2127,7 @@

    Container is running without memory limit

  • - Line number: 22338 + Line number: 22288
  • @@ -2185,7 +2185,7 @@

    Container is running without memory limit

  • - Line number: 22091 + Line number: 22053
  • @@ -2243,7 +2243,7 @@

    Container is running without memory limit

  • - Line number: 22423 + Line number: 22373
  • @@ -2301,7 +2301,7 @@

    Container is running without memory limit

  • - Line number: 22774 + Line number: 22724
  • @@ -2357,7 +2357,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21741 + Line number: 21703
  • @@ -2413,7 +2413,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21859 + Line number: 21821
  • @@ -2469,7 +2469,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21834 + Line number: 21796
  • @@ -2525,7 +2525,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21944 + Line number: 21906
  • @@ -2581,7 +2581,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22027 + Line number: 21989
  • @@ -2637,7 +2637,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22041 + Line number: 22003
  • @@ -2693,7 +2693,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22345 + Line number: 22295
  • @@ -2749,7 +2749,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22311 + Line number: 22261
  • @@ -2805,7 +2805,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22684 + Line number: 22634
  • @@ -2861,7 +2861,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22975 + Line number: 22943
  • diff --git a/docs/snyk/v2.11.8/argocd-iac-namespace-install.html b/docs/snyk/v2.11.12/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.11.8/argocd-iac-namespace-install.html rename to docs/snyk/v2.11.12/argocd-iac-namespace-install.html index 712325c01faa0..11b4414c6af56 100644 --- a/docs/snyk/v2.11.8/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.11.12/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:25:43 am (UTC+00:00)

    +

    December 15th 2024, 12:31:19 am (UTC+00:00)

    Scanned the following path: @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 2036 + Line number: 2054
  • diff --git a/docs/snyk/v2.11.12/argocd-test.html b/docs/snyk/v2.11.12/argocd-test.html new file mode 100644 index 0000000000000..61dbff2086e1b --- /dev/null +++ b/docs/snyk/v2.11.12/argocd-test.html @@ -0,0 +1,21728 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:29:14 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/ui/yarn.lock (yarn)
    • +
    +
    + +
    +
    15 known vulnerabilities
    +
    1089 vulnerable dependency paths
    +
    2041 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.19.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh/knownhosts@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.11.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.11.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.19.0 + + golang.org/x/crypto/ssh@0.19.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + k8s.io/apimachinery/pkg/util/runtime +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and k8s.io/apimachinery/pkg/util/runtime@0.26.11 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.26.11 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.26.11 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/config@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/tools/reference@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.26.11 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/config@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset@0.26.11 + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1@0.26.11 + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset@0.26.11 + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1@0.26.11 + + k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/recorder@0.14.7 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/controller@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/tools/reference@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/tools/reference@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + + k8s.io/api/storage/v1alpha1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/rest/watch@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1/fake@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/v1@0.26.11 + + k8s.io/client-go/tools/clientcmd/api@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + + k8s.io/api/storage/v1alpha1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + + k8s.io/api/storage/v1alpha1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admission/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/admissionregistration/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/apps/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authentication/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/authorization/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/autoscaling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/batch/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/certificates/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/coordination/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/core/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/discovery/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/events/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/extensions/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/flowcontrol/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/imagepolicy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/networking/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/node/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/policy/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/rbac/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/scheduling/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/scale@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/metadata@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/runtime@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/cli-runtime/pkg/genericclioptions@0.26.11 + + k8s.io/client-go/discovery/cached/disk@0.26.11 + + k8s.io/client-go/discovery/cached/memory@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1beta1@1.26.11 + + k8s.io/kubernetes/pkg/features@1.26.11 + + k8s.io/apiserver/pkg/features@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/wait@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/client-go/pkg/apis/clientauthentication/install@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/client-go/util/workqueue@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/util/templates@0.26.11 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/httpstream/spdy@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/plugin/pkg/client/auth/exec@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/kubernetes/typed/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/core/v1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/replace@0.26.11 + + k8s.io/kubectl/pkg/cmd/delete@0.26.11 + + k8s.io/kubectl/pkg/util/completion@0.26.11 + + k8s.io/kubectl/pkg/polymorphichelpers@0.26.11 + + k8s.io/kubectl/pkg/describe@0.26.11 + + k8s.io/client-go/util/certificate/csr@0.26.11 + + k8s.io/client-go/tools/watch@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/util/runtime@0.26.11 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    +

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    +

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    +

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    +

    Two common types of DoS vulnerabilities:

    +
      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • +
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      +
    • +
    +

    Remediation

    +

    Upgrade k8s.io/apimachinery/pkg/util/runtime to version 0.29.0-alpha.3, 1.29.0-alpha.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.26.11 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/soheilhy/cmux@0.1.5 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.21.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.46.1 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.59.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc/health/grpc_health_v1@1.59.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.59.0 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.59.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.59.0 + + google.golang.org/grpc/health/grpc_health_v1@1.59.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.26.11 + + k8s.io/apimachinery/pkg/api/errors@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 + + k8s.io/apimachinery/pkg/api/equality@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.26.11 + + k8s.io/client-go/testing@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/auth@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.26.11 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.26.11 + + k8s.io/client-go/tools/reference@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.26.11 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.26.11 + + k8s.io/client-go/tools/remotecommand@0.26.11 + + k8s.io/client-go/transport/spdy@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + k8s.io/client-go/transport@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + google.golang.org/api/option@0.132.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + k8s.io/client-go/listers/core/v1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 + + k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 + + k8s.io/client-go/tools/cache@0.26.11 + + k8s.io/client-go/tools/pager@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + google.golang.org/api/option@0.132.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb + + k8s.io/kubectl/pkg/cmd/util@0.26.11 + + k8s.io/kubectl/pkg/validation@0.26.11 + + k8s.io/cli-runtime/pkg/resource@0.26.11 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + google.golang.org/api/option@0.132.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 + + k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + k8s.io/client-go/tools/clientcmd@0.26.11 + + k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.26.11 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb + + k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 + + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 + + k8s.io/api/storage/v1alpha1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + google.golang.org/api/option@0.132.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 + + k8s.io/client-go/tools/leaderelection@0.26.11 + + k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 + + k8s.io/client-go/rest@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + google.golang.org/api/chat/v1@0.132.0 + + google.golang.org/api/transport/http@0.132.0 + + google.golang.org/api/option@0.132.0 + + google.golang.org/grpc@1.59.0 + + google.golang.org/grpc/internal/transport@1.59.0 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb + + k8s.io/kubectl/pkg/util/openapi@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 + + k8s.io/client-go/restmapper@0.26.11 + + k8s.io/client-go/discovery@0.26.11 + + k8s.io/client-go/kubernetes/scheme@0.26.11 + + k8s.io/api/storage/v1beta1@0.26.11 + + k8s.io/api/core/v1@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 + + sigs.k8s.io/controller-runtime/pkg/client@0.14.7 + + k8s.io/client-go/dynamic@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 + + k8s.io/apimachinery/pkg/watch@0.26.11 + + k8s.io/apimachinery/pkg/util/net@0.26.11 + + golang.org/x/net/http2@0.19.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/rs/cors +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + github.com/rs/cors@1.9.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    +

    PoC

    +
    
    +        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    +            resps := makeFakeResponses(b.N)
    +            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    +            req.Header.Add(headerOrigin, dummyOrigin)
    +            req.Header.Add(headerACRM, http.MethodGet)
    +            req.Header[headerACRH] = adversarialACRH
    +            handler := Default().Handler(testHandler)
    +        
    +            b.ReportAllocs()
    +            b.ResetTimer()
    +            for i := 0; i < b.N; i++ {
    +                handler.ServeHTTP(resps[i], req)
    +            }
    +        }
    +        
    +        var adversarialACRH []string
    +        
    +        func init() { // populates adversarialACRH
    +            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    +            commas := strings.Repeat(",", n)
    +            res := make([]string, n)
    +            for i := range res {
    +                res[i] = commas
    +            }
    +            adversarialACRH = res
    +        }
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    +

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    +

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    +

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    +

    Two common types of DoS vulnerabilities:

    +
      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • +
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      +
    • +
    +

    Remediation

    +

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.15.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.15.1 + + github.com/hashicorp/go-version@1.2.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    +

    Remediation

    +

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.4 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.13.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/gosimple/slug@1.13.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/Azure/azure-sdk-for-go/sdk/azidentity +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    +

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    +

    Notes:

    +
      +
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      +
    2. +
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      +
    4. +
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      +
    6. +
    7. The vulnerability exists in the following credential types:

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Regular Expression Denial of Service (ReDoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + foundation-sites +
    • + +
    • Introduced through: + + argo-cd-ui@1.0.0 and foundation-sites@6.7.5 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + foundation-sites@6.7.5 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + foundation-sites@6.7.5 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    foundation-sites is a responsive front-end framework

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to inefficient backtracking in the regular expressions used in URL forms.

    +

    PoC

    +
    https://www.''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
    +        
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for foundation-sites.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt/v4 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/golang-jwt/jwt/v4@4.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/go-autorest/autorest/azure@0.11.27 + + github.com/Azure/go-autorest/autorest@0.11.27 + + github.com/Azure/go-autorest/autorest/adal@0.9.20 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 + + github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential@0.5.2 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens@0.5.2 + + github.com/golang-jwt/jwt@3.2.2 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    A fix was pushed into the master branch but not yet published.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html similarity index 68% rename from docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html rename to docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html index d2889ac440c76..fb7ec90e45f43 100644 --- a/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.11.12/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,22 +456,22 @@

    Snyk test report

    -

    September 15th 2024, 12:26:01 am (UTC+00:00)

    +

    December 15th 2024, 12:29:22 am (UTC+00:00)

    Scanned the following paths:
      -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex (apk)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3//usr/local/bin/gomplate (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex//usr/local/bin/dex (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex (apk)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3//usr/local/bin/gomplate (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/dex (gomodules)
    -
    33 known vulnerabilities
    -
    138 vulnerable dependency paths
    -
    786 dependencies
    +
    42 known vulnerabilities
    +
    130 vulnerable dependency paths
    +
    829 dependencies

    @@ -480,7 +480,7 @@

    Snyk test report

    -

    Path Traversal

    +

    Incorrect Implementation of Authentication Algorithm

    @@ -491,7 +491,7 @@

    Path Traversal

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang @@ -499,12 +499,12 @@

      Path Traversal

    • Vulnerable module: - github.com/go-git/go-git/v5 + golang.org/x/crypto/ssh
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5@v5.4.2 + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.18.0
    @@ -519,7 +519,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/go-git/go-git/v5@v5.4.2 + golang.org/x/crypto/ssh@v0.18.0 @@ -531,55 +531,54 @@

    Detailed paths


    Overview

    -

    Affected versions of this package are vulnerable to Path Traversal via malicious server replies. An attacker can create and amend files across the filesystem and potentially achieve remote code execution by sending crafted responses to the client.

    -

    Notes:

    -
      -
    1. This is only exploitable if the client is using ChrootOS, which is the default for certain functions such as PlainClone.

      -
    2. -
    3. Applications using BoundOS or in-memory filesystems are not affected by this issue.

      -
    4. -
    5. Users running versions of go-git from v4 and above are recommended to upgrade to v5.11 in order to mitigate this vulnerability.

      -
    6. -
    -

    Workaround

    -

    This vulnerability can be mitigated by limiting the client's use to trustworthy Git servers.

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    Remediation

    -

    Upgrade github.com/go-git/go-git/v5 to version 5.11.0 or higher.

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    References


    -
    -

    Out-of-bounds Write

    +
    +

    Allocation of Resources Without Limits or Throttling

    -
    - critical severity +
    + high severity

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang
    • Vulnerable module: - busybox/busybox + golang.org/x/net/http2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.19.0
    @@ -592,51 +591,90 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - busybox/busybox@1.36.1-r0 + golang.org/x/net/http2@v0.19.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 + github.com/dexidp/dex@* - busybox/busybox@1.36.1-r0 + golang.org/x/net/http2@v0.20.0
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - +
    - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - +
  • - +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Path Traversal

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/hashicorp/consul/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - busybox/ssl_client@1.36.1-r0 + github.com/hashicorp/consul/api@v1.13.0 @@ -647,37 +685,36 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      There is a stack overflow vulnerability in ash.c:6030 in busybox before 1.35. In the environment of Internet of Vehicles, this vulnerability can be executed from command to arbitrary code execution.

      +

      Overview

      +

      Affected versions of this package are vulnerable to Path Traversal due to a lack of path normalization, when using URL paths in L7 traffic intentions. An attacker could bypass HTTP request path-based access rules, using URL-encoded paths and/or multiple slashes.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r1 or higher.

      +

      Upgrade github.com/hashicorp/consul/api to version 1.20.1 or higher.

      References


    -
    -

    CVE-2023-5363

    +
    +

    Out-of-bounds Write

    -
    - high severity +
    + medium severity

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -687,7 +724,7 @@

      CVE-2023-5363

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -700,75 +737,75 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 @@ -781,86 +818,80 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      Issue summary: A bug has been identified in the processing of key and - initialisation vector (IV) lengths. This can lead to potential truncation - or overruns during the initialisation of some symmetric ciphers.

      -

      Impact summary: A truncation in the IV can result in non-uniqueness, - which could result in loss of confidentiality for some cipher modes.

      -

      When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or - EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after - the key and IV have been established. Any alterations to the key length, - via the "keylen" parameter or the IV length, via the "ivlen" parameter, - within the OSSL_PARAM array will not take effect as intended, potentially - causing truncation or overreading of these values. The following ciphers - and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

      -

      For the CCM, GCM and OCB cipher modes, truncation of the IV can result in - loss of confidentiality. For example, when following NIST's SP 800-38D - section 8.2.1 guidance for constructing a deterministic IV for AES in - GCM mode, truncation of the counter portion could lead to IV reuse.

      -

      Both truncations and overruns of the key and overruns of the IV will - produce incorrect results and could, in some cases, trigger a memory - exception. However, these issues are not currently assessed as security - critical.

      -

      Changing the key and/or IV lengths is not considered to be a common operation - and the vulnerable API was recently introduced. Furthermore it is likely that - application developers will have spotted this problem during testing since - decryption would fail unless both peers in the communication were similarly - vulnerable. For these reasons we expect the probability of an application being - vulnerable to this to be quite low. However if an application is vulnerable then - this issue is considered very serious. For these reasons we have assessed this - issue as Moderate severity overall.

      -

      The OpenSSL SSL/TLS implementation is not affected by this issue.

      -

      The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because - the issue lies outside of the FIPS provider boundary.

      -

      OpenSSL 3.1 and 3.0 are vulnerable to this issue.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      +

      Issue summary: The POLY1305 MAC (message authentication code) implementation + contains a bug that might corrupt the internal state of applications running + on PowerPC CPU based platforms if the CPU provides vector instructions.

      +

      Impact summary: If an attacker can influence whether the POLY1305 MAC + algorithm is used, the application state might be corrupted with various + application dependent consequences.

      +

      The POLY1305 MAC (message authentication code) implementation in OpenSSL for + PowerPC CPUs restores the contents of vector registers in a different order + than they are saved. Thus the contents of some of these vector registers + are corrupted when returning to the caller. The vulnerable code is used only + on newer PowerPC processors supporting the PowerISA 2.07 instructions.

      +

      The consequences of this kind of internal application state corruption can + be various - from no consequences, if the calling application does not + depend on the contents of non-volatile XMM registers at all, to the worst + consequences, where the attacker could get complete control of the application + process. However unless the compiler uses the vector registers for storing + pointers, the most likely consequence, if any, would be an incorrect result + of some application dependent calculations or a crash leading to a denial of + service.

      +

      The POLY1305 MAC algorithm is most frequently used as part of the + CHACHA20-POLY1305 AEAD (authenticated encryption with associated data) + algorithm. The most common usage of this AEAD cipher is with TLS protocol + versions 1.2 and 1.3. If this cipher is enabled on the server a malicious + client can influence whether this AEAD cipher is used. This implies that + TLS server applications using OpenSSL can be potentially impacted. However + we are currently not aware of any concrete application that would be affected + by this issue therefore we consider this a Low severity security issue.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.4-r3 or higher.

      References


    -
    -

    Denial of Service (DoS)

    +
    +

    CVE-2024-0727

    -
    - high severity +
    + medium severity

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • Vulnerable module: - google.golang.org/grpc + openssl/libcrypto3
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -873,18 +904,75 @@

    Detailed paths

    -
    -

    Denial of Service (DoS)

    +
    +

    Infinite loop

    -
    - high severity +
    + medium severity

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang @@ -946,12 +1043,12 @@

      Denial of Service (DoS)

    • Vulnerable module: - golang.org/x/net/http2 + google.golang.org/protobuf/internal/encoding/json
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.31.0
    @@ -966,7 +1063,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - golang.org/x/net/http2@v0.7.0 + google.golang.org/protobuf/internal/encoding/json@v1.31.0 @@ -975,7 +1072,7 @@

    Detailed paths

    Introduced through: github.com/dexidp/dex@* - golang.org/x/net/http2@v0.11.0 + google.golang.org/protobuf/internal/encoding/json@v1.32.0 @@ -987,49 +1084,38 @@

    Detailed paths


    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function, by unmarshaling certain forms of invalid JSON.

    +

    Note:

    +

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    References


    -
    -

    Allocation of Resources Without Limits or Throttling

    +
    +

    Stack-based Buffer Overflow

    -
    - high severity +
    + medium severity

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang @@ -1037,12 +1123,12 @@

      Allocation of Resources Without Limits or Throttling

      Vulnerable module: - golang.org/x/net/http2 + google.golang.org/protobuf/encoding/protojson
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0
    @@ -1057,59 +1143,48 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - golang.org/x/net/http2@v0.7.0 + google.golang.org/protobuf/encoding/protojson@v1.31.0 -
  • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.11.0 - - - -
  • - +

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    +

    Affected versions of this package are vulnerable to Stack-based Buffer Overflow when processing input that uses pathologically deep nesting.

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    +

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.32.0 or higher.

    References


    -
    -

    Heap-based Buffer Overflow

    +
    +

    Infinite loop

    -
    - high severity +
    + medium severity

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang @@ -1117,12 +1192,12 @@

      Heap-based Buffer Overflow

    • Vulnerable module: - github.com/mattn/go-sqlite3 + google.golang.org/protobuf/encoding/protojson
    • Introduced through: - github.com/dexidp/dex@* and github.com/mattn/go-sqlite3@v1.14.17 + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0
    @@ -1135,79 +1210,18 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + github.com/hairyhenderson/gomplate/v3@* - github.com/mattn/go-sqlite3@v1.14.17 + google.golang.org/protobuf/encoding/protojson@v1.31.0
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Heap-based Buffer Overflow via the sessionReadRecord function in the ext/session/sqlite3session.c file. An attacker can cause a program crash or execute arbitrary code by manipulating the input to trigger a heap-based buffer overflow.

    -

    Remediation

    -

    Upgrade github.com/mattn/go-sqlite3 to version 1.14.18 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
    • Introduced through: github.com/dexidp/dex@* - github.com/go-jose/go-jose/v3@v3.0.0 + google.golang.org/protobuf/encoding/protojson@v1.32.0 @@ -1219,37 +1233,27 @@

      Detailed paths


      Overview

      -

      Affected versions of this package are vulnerable to Denial of Service (DoS) when decrypting JWE inputs. An attacker can cause a denial-of-service by providing a PBES2 encrypted JWE blob with a very large p2c value.

      -

      Details

      -

      Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

      -

      Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

      -

      One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

      -

      When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

      -

      Two common types of DoS vulnerabilities:

      -
        -
      • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

        -
      • -
      • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

        -
      • -
      +

      Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function, by unmarshaling certain forms of invalid JSON.

      +

      Note:

      +

      This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

      Remediation

      -

      Upgrade github.com/go-jose/go-jose/v3 to version 3.0.1 or higher.

      +

      Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

      References


    -

    Improper Authentication

    +

    MPL-2.0 license

    @@ -1260,17 +1264,20 @@

    Improper Authentication

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • - Vulnerable module: + Package Manager: golang +
    • +
    • + Module: - openssl/libcrypto3 + github.com/hashicorp/vault/sdk/helper/certutil
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0
    @@ -1283,75 +1290,54 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libssl3@3.1.1-r1 + github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 + github.com/hairyhenderson/gomplate/v3@* - openssl/libssl3@3.1.1-r1 + github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libssl3@3.1.1-r1 + github.com/hashicorp/vault/sdk/logical@v0.5.0 @@ -1362,48 +1348,17 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      Issue summary: The AES-SIV cipher implementation contains a bug that causes - it to ignore empty associated data entries which are unauthenticated as - a consequence.

      -

      Impact summary: Applications that use the AES-SIV algorithm and want to - authenticate empty data entries as associated data can be mislead by removing - adding or reordering such empty entries as these are ignored by the OpenSSL - implementation. We are currently unaware of any such applications.

      -

      The AES-SIV algorithm allows for authentication of multiple associated - data entries along with the encryption. To authenticate empty data the - application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with - NULL pointer as the output buffer and 0 as the input buffer length. - The AES-SIV implementation in OpenSSL just returns success for such a call - instead of performing the associated data authentication operation. - The empty data thus will not be authenticated.

      -

      As this issue does not affect non-empty associated data authentication and - we expect it to be rare for an application to use empty associated data - entries this is qualified as Low severity issue.

      -

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.1-r2 or higher.

      -

      References

      - +

      MPL-2.0 license


    -

    Inefficient Regular Expression Complexity

    +

    MPL-2.0 license

    @@ -1414,17 +1369,20 @@

    Inefficient Regular Expression Complexity

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • - Vulnerable module: + Package Manager: golang +
    • +
    • + Module: - openssl/libcrypto3 + github.com/hashicorp/vault/api
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0
    @@ -1437,75 +1395,69 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/vault/api@v1.6.0
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - +
    - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - +
  • - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - +
    + +

    MPL-2.0 license

    -
  • -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - +
    -
  • -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - + -
  • +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/serf/coordinate +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    Excessive Iteration

    +

    MPL-2.0 license

    @@ -1579,17 +1489,20 @@

    Excessive Iteration

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • - Vulnerable module: + Package Manager: golang +
    • +
    • + Module: - openssl/libcrypto3 + github.com/hashicorp/hcl/v2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0
    @@ -1602,75 +1515,72 @@

    Detailed paths

    -

    Improper Check for Unusual or Exceptional Conditions

    +

    MPL-2.0 license

    @@ -1744,17 +1612,20 @@

    Improper Check for Unusual or Exceptional Conditions

  • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
  • - Vulnerable module: + Package Manager: golang +
  • +
  • + Module: - openssl/libcrypto3 + github.com/hashicorp/hcl
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0
  • @@ -1767,75 +1638,78 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/hcl@v1.0.0
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/hcl/hcl/token@v1.0.0
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - +
    - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - +
  • - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - +
    + +

    MPL-2.0 license

    -
  • -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - +
    -
  • + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/golang-lru/simplelru +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    Out-of-bounds Write

    +

    MPL-2.0 license

    @@ -1906,17 +1741,20 @@

    Out-of-bounds Write

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • - Vulnerable module: + Package Manager: golang +
    • +
    • + Module: - openssl/libcrypto3 + github.com/hashicorp/go-version
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0
    @@ -1929,75 +1767,318 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/go-version@v1.5.0
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-sockaddr +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/go-sockaddr@v1.0.2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/go-sockaddr/template@v1.0.2
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/strutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/parseutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libssl3@3.1.1-r1 + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/mlock +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 + github.com/hairyhenderson/gomplate/v3@* - openssl/libssl3@3.1.1-r1 + github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-rootcerts +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    CVE-2024-0727

    +

    Insertion of Sensitive Information into Log File

    @@ -2073,17 +2110,20 @@

    CVE-2024-0727

    • - Package Manager: alpine:3.18 + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang
    • Vulnerable module: - openssl/libcrypto3 + github.com/hashicorp/go-retryablehttp
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1
    @@ -2096,75 +2136,77 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + github.com/hairyhenderson/gomplate/v3@* - openssl/libcrypto3@3.1.1-r1 + github.com/hashicorp/go-retryablehttp@v0.7.1
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - +
    - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - +
  • - -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    +

    Remediation

    +

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    +

    References

    + -
  • -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - +
    -
  • -
  • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - + -
  • +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    Infinite loop

    +

    MPL-2.0 license

    @@ -2227,20 +2238,20 @@

    Infinite loop

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - google.golang.org/protobuf/internal/encoding/json + github.com/hashicorp/go-plugin
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.28.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4
    @@ -2255,16 +2266,16 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/internal/encoding/json@v1.28.0 + github.com/hashicorp/go-plugin@v1.4.4
  • Introduced through: - github.com/dexidp/dex@* + github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/internal/encoding/json@v1.31.0 + github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 @@ -2275,28 +2286,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    -

    References

    - +

    MPL-2.0 license


  • -

    Stack-based Buffer Overflow

    +

    MPL-2.0 license

    @@ -2307,20 +2307,20 @@

    Stack-based Buffer Overflow

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - google.golang.org/protobuf/encoding/protojson + github.com/hashicorp/go-immutable-radix
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.28.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1
    @@ -2335,16 +2335,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/encoding/protojson@v1.28.0 - - - - -
  • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 + github.com/hashicorp/go-immutable-radix@v1.3.1 @@ -2355,25 +2346,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Stack-based Buffer Overflow when processing input that uses pathologically deep nesting.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.32.0 or higher.

    -

    References

    - +

    MPL-2.0 license


  • -

    Infinite loop

    +

    MPL-2.0 license

    @@ -2384,20 +2367,20 @@

    Infinite loop

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - google.golang.org/protobuf/encoding/protojson + github.com/hashicorp/go-cleanhttp
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.28.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2
    @@ -2412,16 +2395,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/encoding/protojson@v1.28.0 - - - - -
  • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 + github.com/hashicorp/go-cleanhttp@v0.5.2 @@ -2432,28 +2406,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

    -

    References

    - +

    MPL-2.0 license


  • -

    Allocation of Resources Without Limits or Throttling

    +

    MPL-2.0 license

    @@ -2464,20 +2427,20 @@

    Allocation of Resources Without Limits or Throttling

  • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
  • Package Manager: golang
  • - Vulnerable module: + Module: - golang.org/x/net/http2 + github.com/hashicorp/errwrap
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0
  • @@ -2492,16 +2455,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - golang.org/x/net/http2@v0.7.0 - - - - -
  • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.11.0 + github.com/hashicorp/errwrap@v1.1.0 @@ -2512,29 +2466,17 @@

    Detailed paths


    -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when MaxConcurrentStreams handler goroutines running. A a handler is started until one of the existing handlers exits.

    -

    Note:

    -

    This issue is related to CVE-2023-44487

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    -

    References

    - +

    MPL-2.0 license


  • -

    Cross-site Scripting (XSS)

    +

    Access Control Bypass

    @@ -2545,7 +2487,7 @@

    Cross-site Scripting (XSS)

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang @@ -2553,12 +2495,12 @@

      Cross-site Scripting (XSS)

    • Vulnerable module: - golang.org/x/net/html + github.com/hashicorp/consul/api
    • Introduced through: - github.com/dexidp/dex@* and golang.org/x/net/html@v0.11.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -2571,9 +2513,9 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + github.com/hairyhenderson/gomplate/v3@* - golang.org/x/net/html@v0.11.0 + github.com/hashicorp/consul/api@v1.13.0 @@ -2585,82 +2527,24 @@

      Detailed paths


      Overview

      -

      golang.org/x/net/html is a package that implements an HTML5-compliant tokenizer and parser.

      -

      Affected versions of this package are vulnerable to Cross-site Scripting (XSS) in the render1() function in render.go. Text nodes not in the HTML namespace are incorrectly literally rendered, causing text which should be escaped to not be.

      -

      Details

      -

      A cross-site scripting attack occurs when the attacker tricks a legitimate web-based application or site to accept a request as originating from a trusted source.

      -

      This is done by escaping the context of the web application; the web application then delivers that data to its users along with other trusted dynamic content, without validating it. The browser unknowingly executes malicious script on the client side (through client-side languages; usually JavaScript or HTML) in order to perform actions that are otherwise typically blocked by the browser’s Same Origin Policy.

      -

      Injecting malicious code is the most prevalent manner by which XSS is exploited; for this reason, escaping characters in order to prevent this manipulation is the top method for securing code against this vulnerability.

      -

      Escaping means that the application is coded to mark key characters, and particularly key characters included in user input, to prevent those characters from being interpreted in a dangerous context. For example, in HTML, < can be coded as &lt; and > can be coded as &gt; in order to be interpreted and displayed as themselves in text, while within the code itself, they are used for HTML tags. If malicious content is injected into an application that escapes special characters and that malicious content uses < and > as HTML tags, those characters are nonetheless not interpreted as HTML tags by the browser if they’ve been correctly escaped in the application code and in this way the attempted attack is diverted.

      -

      The most prominent use of XSS is to steal cookies (source: OWASP HttpOnly) and hijack user sessions, but XSS exploits have been used to expose sensitive information, enable access to privileged services and functionality and deliver malware.

      -

      Types of attacks

      -

      There are a few methods by which XSS can be manipulated:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      TypeOriginDescription
      StoredServerThe malicious code is inserted in the application (usually as a link) by the attacker. The code is activated every time a user clicks the link.
      ReflectedServerThe attacker delivers a malicious link externally from the vulnerable web site application to a user. When clicked, malicious code is sent to the vulnerable web site, which reflects the attack back to the user’s browser.
      DOM-basedClientThe attacker forces the user’s browser to render a malicious page. The data in the page itself delivers the cross-site scripting data.
      MutatedThe attacker injects code that appears safe, but is then rewritten and modified by the browser, while parsing the markup. An example is rebalancing unclosed quotation marks or even adding quotation marks to unquoted parameters.
      -

      Affected environments

      -

      The following environments are susceptible to an XSS attack:

      -
        -
      • Web servers
      • -
      • Application servers
      • -
      • Web application environments
      • -
      -

      How to prevent

      -

      This section describes the top best practices designed to specifically protect your code:

      -
        -
      • Sanitize data input in an HTTP request before reflecting it back, ensuring all data is validated, filtered or escaped before echoing anything back to the user, such as the values of query parameters during searches.
      • -
      • Convert special characters such as ?, &, /, <, > and spaces to their respective HTML or URL encoded equivalents.
      • -
      • Give users the option to disable client-side scripts.
      • -
      • Redirect invalid requests.
      • -
      • Detect simultaneous logins, including those from two separate IP addresses, and invalidate those sessions.
      • -
      • Use and enforce a Content Security Policy (source: Wikipedia) to disable any features that might be manipulated for an XSS attack.
      • -
      • Read the documentation for any of the libraries referenced in your code to understand which elements allow for embedded HTML.
      • -
      +

      Affected versions of this package are vulnerable to Access Control Bypass due to a lack of header normalization while using Headers in L7 traffic intentions. By exploiting this, an attacker could bypass HTTP header based access rules.

      Remediation

      -

      Upgrade golang.org/x/net/html to version 0.13.0 or higher.

      +

      Upgrade github.com/hashicorp/consul/api to version 1.20.1 or higher.

      References


    -

    Authentication Bypass by Capture-replay

    +

    MPL-2.0 license

    @@ -2671,20 +2555,20 @@

    Authentication Bypass by Capture-replay

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - golang.org/x/crypto/ssh + github.com/hashicorp/consul/api
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.0.0-20220525230936-793ad666bf5e + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -2699,7 +2583,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - golang.org/x/crypto/ssh@v0.0.0-20220525230936-793ad666bf5e + github.com/hashicorp/consul/api@v1.13.0 @@ -2710,55 +2594,17 @@

    Detailed paths


    -

    Overview

    -

    golang.org/x/crypto/ssh is a SSH client and server

    -

    Affected versions of this package are vulnerable to Authentication Bypass by Capture-replay during the establishment of the secure channel. An attacker can manipulate handshake sequence numbers to delete messages sent immediately after the channel is established.

    -

    Note:

    -
      -
    1. Sequence numbers are only validated once the channel is established and arbitrary messages are allowed during the handshake, allowing them to manipulate the sequence numbers.

      -
    2. -
    3. The potential consequences of the general Terrapin attack are dependent on the messages exchanged after the handshake concludes. If you are using a custom SSH service and do not resort to the authentication protocol, you should check that dropping the first few messages of a connection does not yield security risks.

      -
    4. -
    -

    Impact:

    -

    While cryptographically novel, there is no discernable impact on the integrity of SSH traffic beyond giving the attacker the ability to delete the message that enables some features related to keystroke timing obfuscation. To successfully carry out the exploitation, the connection needs to be protected using either the ChaCha20-Poly1305 or CBC with Encrypt-then-MAC encryption methods. The attacker must also be able to intercept and modify the connection's traffic.

    -

    Workaround

    -

    Temporarily disable the affected chacha20-poly1305@openssh.com encryption and *-etm@openssh.com MAC algorithms in the affected configuration, and use unaffected algorithms like AES-GCM instead.

    -

    Remediation

    -

    Upgrade golang.org/x/crypto/ssh to version 0.17.0 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -2769,20 +2615,20 @@

    Insertion of Sensitive Information into Log File

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/hashicorp/go-retryablehttp + github.com/gosimple/slug
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0
    @@ -2797,7 +2643,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/gosimple/slug@v1.12.0 @@ -2808,25 +2654,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Improper Handling of Highly Compressed Data (Data Amplification)

    +

    MPL-2.0 license

    @@ -2837,20 +2675,20 @@

    Improper Handling of Highly Compressed Data (Data Amplif
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/go-jose/go-jose/v3 + github.com/go-sql-driver/mysql
    • Introduced through: - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1
    @@ -2865,7 +2703,7 @@

    Detailed paths

    Introduced through: github.com/dexidp/dex@* - github.com/go-jose/go-jose/v3@v3.0.0 + github.com/go-sql-driver/mysql@v1.7.1 @@ -2876,26 +2714,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Uncontrolled Resource Consumption ('Resource Exhaustion')

    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    @@ -2906,7 +2735,7 @@

    Uncontrolled Resource Consumption ('Resource Exhaus
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang @@ -2914,12 +2743,12 @@

      Uncontrolled Resource Consumption ('Resource Exhaus
    • Vulnerable module: - github.com/go-git/go-git/v5/plumbing + github.com/go-jose/go-jose/v3
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing@v5.4.2 + github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1
    @@ -2932,9 +2761,9 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + github.com/dexidp/dex@* - github.com/go-git/go-git/v5/plumbing@v5.4.2 + github.com/go-jose/go-jose/v3@v3.0.1 @@ -2946,35 +2775,20 @@

      Detailed paths


      Overview

      -

      github.com/go-git/go-git/v5/plumbing is a highly extensible git implementation library written in pure Go.

      -

      Affected versions of this package are vulnerable to Uncontrolled Resource Consumption ('Resource Exhaustion') via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

      -

      Note - This is only exploitable if the client is not using the in-memory filesystem supported by the library.

      -

      Workaround

      -

      In cases where a bump to the latest version of go-git is not possible, we recommend limiting its use to only trust-worthy Git servers.

      -

      Details

      -

      Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

      -

      Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

      -

      One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

      -

      When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

      -

      Two common types of DoS vulnerabilities:

      -
        -
      • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

        -
      • -
      • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

        -
      • -
      +

      Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

      Remediation

      -

      Upgrade github.com/go-git/go-git/v5/plumbing to version 5.11.0 or higher.

      +

      Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

      References


    @@ -2990,7 +2804,7 @@

    Out-of-bounds Write

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3000,7 +2814,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -3013,51 +2827,51 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 @@ -3070,19 +2884,20 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r6 or higher.

      +

      Upgrade Alpine:3.19 busybox to version 1.36.1-r16 or higher.

      References


    @@ -3098,7 +2913,7 @@

    Use After Free

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3108,7 +2923,7 @@

      Use After Free

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -3121,51 +2936,51 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 @@ -3178,19 +2993,19 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      +

      A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

      +

      Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

      References


    @@ -3206,7 +3021,7 @@

    Use After Free

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3216,7 +3031,7 @@

      Use After Free

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -3229,51 +3044,51 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 @@ -3286,10 +3101,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

      +

      Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

      References

    @@ -3314,7 +3129,7 @@

    Use After Free

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3324,7 +3139,7 @@

      Use After Free

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -3337,51 +3152,51 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15 - busybox/busybox@1.36.1-r0 + busybox/busybox@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + alpine-baselayout/alpine-baselayout@3.4.3-r2 - busybox/busybox-binsh@1.36.1-r0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 @@ -3394,19 +3209,19 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      +

      A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

      +

      Upgrade Alpine:3.19 busybox to version 1.36.1-r17 or higher.

      References


    @@ -3422,7 +3237,7 @@

    CVE-2023-6237

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3432,7 +3247,7 @@

      CVE-2023-6237

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -3445,75 +3260,75 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 @@ -3526,7 +3341,7 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      Issue summary: Checking excessively long invalid RSA public keys may take a long time.

      Impact summary: Applications that use the function EVP_PKEY_public_check() @@ -3548,21 +3363,21 @@

      NVD Description

      The OpenSSL SSL/TLS implementation is not affected by this issue.

      The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r4 or higher.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.4-r4 or higher.

      References


    @@ -3578,7 +3393,7 @@

    CVE-2024-2511

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3588,7 +3403,7 @@

      CVE-2024-2511

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -3601,75 +3416,75 @@

    Detailed paths

    @@ -3730,7 +3545,7 @@

    CVE-2024-4603

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3740,7 +3555,7 @@

      CVE-2024-4603

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -3753,75 +3568,75 @@

    Detailed paths

    @@ -3890,7 +3705,7 @@

    CVE-2024-5535

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -3900,7 +3715,7 @@

      CVE-2024-5535

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -3913,75 +3728,75 @@

    Detailed paths

    @@ -4085,7 +3901,7 @@

    CVE-2024-4741

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -4095,7 +3911,7 @@

      CVE-2024-4741

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -4108,75 +3924,75 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 @@ -4188,14 +4004,48 @@

      Detailed paths


      NVD Description

      -

      This vulnerability has not been analyzed by NVD yet.

      +

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      +

      Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

      +

      Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

      +

      The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

      +

      The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

      +

      The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

      +

      While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

      +

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.6-r0 or higher.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

      +

      References

      +
    @@ -4211,7 +4061,7 @@

    CVE-2024-6119

    • - Package Manager: alpine:3.18 + Package Manager: alpine:3.19
    • Vulnerable module: @@ -4221,7 +4071,7 @@

      CVE-2024-6119

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
    @@ -4234,75 +4084,75 @@

    Detailed paths

    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 - openssl/libcrypto3@3.1.1-r1 + openssl/libcrypto3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - apk-tools/apk-tools@2.14.0-r2 + apk-tools/apk-tools@2.14.0-r5 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2
    • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/ssl_client@1.36.1-r0 + busybox/ssl_client@1.36.1-r15 - openssl/libssl3@3.1.1-r1 + openssl/libssl3@3.1.4-r2 @@ -4315,7 +4165,7 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      + See How to fix? for Alpine:3.19 relevant fixed versions and status.

      Issue summary: Applications performing certificate name checks (e.g., TLS clients checking server certificates) may attempt to read an invalid memory address resulting in abnormal termination of the application process.

      @@ -4336,7 +4186,7 @@

      NVD Description

      of the issue is Moderate.

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.7-r0 or higher.

      +

      Upgrade Alpine:3.19 openssl to version 3.1.7-r0 or higher.

      References

      + +
      + + + +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.19 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.19 openssl to version 3.1.7-r1 or higher.

    +

    References

    +
    diff --git a/docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html b/docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html similarity index 89% rename from docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html index bb20c3cb21a3c..3e1a3e3b56dc0 100644 --- a/docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.11.12/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:26:05 am (UTC+00:00)

    +

    December 15th 2024, 12:29:27 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    14 known vulnerabilities
    -
    110 vulnerable dependency paths
    +
    15 known vulnerabilities
    +
    119 vulnerable dependency paths
    18 dependencies
    @@ -661,13 +661,13 @@

    Remediation

    References


    @@ -845,13 +845,13 @@

    Remediation

    References


    @@ -1032,15 +1032,15 @@

    Remediation

    References


    @@ -1209,14 +1209,14 @@

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.4-r5 or higher.

    References


    @@ -1325,6 +1325,7 @@

    Remediation

    References


    @@ -1821,12 +1822,12 @@

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.4-r4 or higher.

    References


    @@ -1994,13 +1995,13 @@

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.4-r6 or higher.

    References


    @@ -2176,13 +2177,13 @@

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.5-r0 or higher.

    References


    @@ -2390,16 +2391,17 @@

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.6-r0 or higher.

    References


    @@ -2546,9 +2548,43 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

    +

    Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

    +

    The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

    +

    The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

    +

    The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

    +

    While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    Remediation

    Upgrade Alpine:3.18 openssl to version 3.1.6-r0 or higher.

    +

    References

    +
    @@ -2724,6 +2760,9 @@

    References

  • https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2
  • https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0
  • https://openssl-library.org/news/secadv/20240903.txt
  • +
  • http://www.openwall.com/lists/oss-security/2024/09/03/4
  • +
  • https://lists.freebsd.org/archives/freebsd-security/2024-September/000303.html
  • +
  • https://security.netapp.com/advisory/ntap-20240912-0001/

  • @@ -2733,6 +2772,191 @@

    References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.7-r1 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html b/docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html similarity index 77% rename from docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html rename to docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html index 92b035cf413d0..30082caf72a84 100644 --- a/docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html +++ b/docs/snyk/v2.11.12/quay.io_argoproj_argocd_v2.11.12.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    September 15th 2024, 12:26:23 am (UTC+00:00)

    +

    December 15th 2024, 12:29:45 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.10.16/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.16//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.16/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.16/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.12/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    34 known vulnerabilities
    -
    236 vulnerable dependency paths
    -
    2278 dependencies
    +
    38 known vulnerabilities
    +
    210 vulnerable dependency paths
    +
    2280 dependencies
    @@ -480,19 +480,19 @@

    Snyk test report

    -
    -

    Allocation of Resources Without Limits or Throttling

    +
    +

    Incorrect Implementation of Authentication Algorithm

    -
    - high severity +
    + critical severity

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang @@ -500,12 +500,12 @@

      Allocation of Resources Without Limits or Throttling

      Vulnerable module: - golang.org/x/net/http2 + golang.org/x/crypto/ssh
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.19.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.19.0
    @@ -520,16 +520,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - golang.org/x/net/http2@v0.19.0 - - - - -
  • - Introduced through: - helm.sh/helm/v3@* - - golang.org/x/net/http2@v0.17.0 + golang.org/x/crypto/ssh@v0.19.0 @@ -541,51 +532,54 @@

    Detailed paths


    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    References


  • -
    -

    CVE-2024-41996

    +
    +

    Denial of Service (DoS)

    -
    - medium severity +
    + high severity

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • Vulnerable module: - openssl/libssl3 + k8s.io/apimachinery/pkg/util/runtime
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 + github.com/argoproj/argo-cd/v2@* and k8s.io/apimachinery/pkg/util/runtime@v0.26.11
    @@ -598,113 +592,112 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + github.com/argoproj/argo-cd/v2@* - openssl/libssl3@3.0.2-0ubuntu1.16 + k8s.io/apimachinery/pkg/util/runtime@v0.26.11
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    +

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    +

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    +

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    +

    Two common types of DoS vulnerabilities:

    +
      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • +
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      +
    • +
    +

    Remediation

    +

    Upgrade k8s.io/apimachinery/pkg/util/runtime to version 0.29.0-alpha.3, 1.29.0-alpha.3 or higher.

    +

    References

    + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
  • +
    +

    Allocation of Resources Without Limits or Throttling

    +
    - +
    + high severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.19.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + github.com/argoproj/argo-cd/v2@* - openssl@3.0.2-0ubuntu1.16 + golang.org/x/net/http2@v0.19.0
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 + helm.sh/helm/v3@* - openssl@3.0.2-0ubuntu1.16 + golang.org/x/net/http2@v0.17.0 @@ -715,29 +708,29 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      +

      Overview

      +

      golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

      +

      Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

      References


    -

    CVE-2024-6119

    +

    Insecure Storage of Sensitive Information

    @@ -748,7 +741,7 @@

    CVE-2024-6119

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -756,12 +749,12 @@

      CVE-2024-6119

    • Vulnerable module: - openssl/libssl3 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pam/libpam0g@1.4.0-11ubuntu2.4
    @@ -774,77 +767,92 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + shadow/login@1:4.8.1-2ubuntu2.2 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - libfido2/libfido2-1@1.10.0-1 + util-linux@2.37.2-4ubuntu3.4 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - ca-certificates@20230311ubuntu0.22.04.1 + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 - openssl@3.0.2-0ubuntu1.16 + pam/libpam-modules@1.4.0-11ubuntu2.4 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - git@1:2.34.1-1ubuntu1.11 + adduser@3.118ubuntu5 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + pam/libpam-modules-bin@1.4.0-11ubuntu2.4 + + pam/libpam0g@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -852,35 +860,71 @@

      Detailed paths

      pam/libpam-modules@1.4.0-11ubuntu2.4 - libnsl/libnsl2@1.3.0-2build2 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4 + +
      + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + pam/libpam-runtime@1.4.0-11ubuntu2.4 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + shadow/login@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + adduser@3.118ubuntu5 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + shadow/passwd@1:4.8.1-2ubuntu2.2 - openssl/libssl3@3.0.2-0ubuntu1.16 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl@3.0.2-0ubuntu1.16 + pam/libpam-runtime@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - ca-certificates@20230311ubuntu0.22.04.1 + shadow/login@1:4.8.1-2ubuntu2.2 - openssl@3.0.2-0ubuntu1.16 + pam/libpam-runtime@1.4.0-11ubuntu2.4 @@ -892,48 +936,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Applications performing certificate name checks (e.g., TLS - clients checking server certificates) may attempt to read an invalid memory - address resulting in abnormal termination of the application process.

      -

      Impact summary: Abnormal termination of an application can a cause a denial of - service.

      -

      Applications performing certificate name checks (e.g., TLS clients checking - server certificates) may attempt to read an invalid memory address when - comparing the expected name with an otherName subject alternative name of an - X.509 certificate. This may result in an exception that terminates the - application program.

      -

      Note that basic certificate chain validation (signatures, dates, ...) is not - affected, the denial of service can occur only when the application also - specifies an expected DNS name, Email address or IP address.

      -

      TLS servers rarely solicit client certificates, and even when they do, they - generally don't perform a name check against a reference identifier (expected - identity), but rather extract the presented identity after checking the - certificate chain. So TLS servers are generally not affected and the severity - of the issue is Moderate.

      -

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      +

      A vulnerability was found in PAM. The secret information is stored in memory, where the attacker can trigger the victim program to execute by sending characters to its standard input (stdin). As this occurs, the attacker can train the branch predictor to execute an ROP chain speculatively. This flaw could result in leaked passwords, such as those found in /etc/shadow while performing authentications.

      Remediation

      -

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.18 or higher.

      +

      There is no fixed version for Ubuntu:22.04 pam.

      References


    -

    Information Exposure

    +

    Improper Authentication

    @@ -944,7 +969,7 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -952,12 +977,12 @@

      Information Exposure

    • Vulnerable module: - libgcrypt20 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and libgcrypt20@1.9.4-3ubuntu3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pam/libpam0g@1.4.0-11ubuntu2.4
    @@ -970,150 +995,164 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + shadow/login@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gpg@2.2.27-3ubuntu2.1 + util-linux@2.37.2-4ubuntu3.4 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + adduser@3.118ubuntu5 - apt/libapt-pkg6.0@2.4.12 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + adduser@3.118ubuntu5 - gnupg2/gpgv@2.2.27-3ubuntu2.1 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gpg@2.2.27-3ubuntu2.1 + adduser@3.118ubuntu5 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + pam/libpam-modules-bin@1.4.0-11ubuntu2.4 + + pam/libpam0g@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + adduser@3.118ubuntu5 - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + pam/libpam-modules-bin@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + pam/libpam-modules@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + pam/libpam-runtime@1.4.0-11ubuntu2.4 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + shadow/login@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + adduser@3.118ubuntu5 - gnupg2/gpgsm@2.2.27-3ubuntu2.1 + shadow/passwd@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.4.0-11ubuntu2.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - apt@2.4.12 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt/libapt-pkg6.0@2.4.12 + pam/libpam-runtime@1.4.0-11ubuntu2.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 - systemd/libsystemd0@249.11-0ubuntu3.12 + shadow/login@1:4.8.1-2ubuntu2.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-runtime@1.4.0-11ubuntu2.4 @@ -1125,23 +1164,22 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

      +

      A flaw was found in pam_access, where certain rules in its configuration file are mistakenly treated as hostnames. This vulnerability allows attackers to trick the system by pretending to be a trusted hostname, gaining unauthorized access. This issue poses a risk for systems that rely on this feature to control who can access certain services or terminals.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 libgcrypt20.

      +

      There is no fixed version for Ubuntu:22.04 pam.

      References


    @@ -1157,7 +1195,7 @@

    CVE-2024-26462

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -1170,7 +1208,7 @@

      CVE-2024-26462

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
    @@ -1183,16 +1221,16 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -1204,16 +1242,16 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -1225,27 +1263,27 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -1257,64 +1295,64 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -1326,16 +1364,16 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -1367,7 +1405,7 @@

      References

    -

    CVE-2024-37371

    +

    LGPL-3.0 license

    @@ -1378,20 +1416,20 @@

    CVE-2024-37371

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - krb5/libk5crypto3 + gopkg.in/retry.v1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3
    @@ -1404,159 +1442,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libk5crypto3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libk5crypto3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - krb5/libk5crypto3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + github.com/argoproj/argo-cd/v2@* - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + gopkg.in/retry.v1@v1.0.3 @@ -1567,28 +1455,17 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      In MIT Kerberos 5 (aka krb5) before 1.21.3, an attacker can cause invalid memory reads during GSS message token handling by sending message tokens with invalid length fields.

      -

      Remediation

      -

      Upgrade Ubuntu:22.04 krb5 to version 1.19.2-2ubuntu0.4 or higher.

      -

      References

      - +

      LGPL-3.0 license


    -

    CVE-2024-37370

    +

    Denial of Service (DoS)

    @@ -1599,20 +1476,20 @@

    CVE-2024-37370

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • Vulnerable module: - krb5/libk5crypto3 + github.com/rs/cors
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0
    @@ -1625,237 +1502,16 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libk5crypto3@1.19.2-2ubuntu0.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + github.com/argoproj/argo-cd/v2@* - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + github.com/rs/cors@v1.9.0
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - krb5/libk5crypto3@1.19.2-2ubuntu0.3 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - krb5/libkrb5support0@1.19.2-2ubuntu0.3 - - - -
  • - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    In MIT Kerberos 5 (aka krb5) before 1.21.3, an attacker can modify the plaintext Extra Count field of a confidential GSS krb5 wrap token, causing the unwrapped token to appear truncated to the application.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 krb5 to version 1.19.2-2ubuntu0.4 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/rs/cors -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/rs/cors@v1.9.0 - - - -
    • -
    - -
    +

    @@ -1897,7 +1553,7 @@

    Details

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    Two common types of DoS vulnerabilities:

      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

    • @@ -1919,7 +1575,7 @@

      References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -1930,20 +1586,20 @@

    Insertion of Sensitive Information into Log File

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/hashicorp/go-retryablehttp + github.com/r3labs/diff
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0
    @@ -1958,7 +1614,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - github.com/hashicorp/go-retryablehttp@v0.7.4 + github.com/r3labs/diff@v1.1.0 @@ -1969,25 +1625,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1998,21 +1646,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-version
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1 - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -2024,11 +1672,9 @@

    Detailed paths

    -

    XML External Entity (XXE) Injection

    +

    Insertion of Sensitive Information into Log File

    @@ -2071,21 +1706,21 @@

    XML External Entity (XXE) Injection

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • Vulnerable module: - expat/libexpat1 + github.com/hashicorp/go-retryablehttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -2097,11 +1732,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 + github.com/argoproj/argo-cd/v2@* - expat/libexpat1@2.4.7-1ubuntu0.3 + github.com/hashicorp/go-retryablehttp@v0.7.4 @@ -2112,28 +1745,25 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream expat package and not the expat package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      An issue was discovered in libexpat before 2.6.3. xmlparse.c does not reject a negative length for XML_ParseBuffer.

      +

      Overview

      +

      Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 expat.

      +

      Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

      References


    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -2144,21 +1774,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-retryablehttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -2170,11 +1800,9 @@

    Detailed paths

    -

    Out-of-bounds Read

    +

    MPL-2.0 license

    @@ -2217,21 +1834,21 @@

    Out-of-bounds Read

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/helm/v3 /usr/local/bin/helm
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - curl/libcurl3-gnutls + github.com/hashicorp/go-multierror
    • Introduced through: + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -2243,11 +1860,9 @@

    Detailed paths

    -

    CVE-2024-8096

    +

    MPL-2.0 license

    @@ -2299,21 +1894,21 @@

    CVE-2024-8096

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - curl/libcurl3-gnutls + github.com/hashicorp/go-cleanhttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -2325,11 +1920,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 + github.com/argoproj/argo-cd/v2@* - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + github.com/hashicorp/go-cleanhttp@v0.5.2 @@ -2340,53 +1933,41 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      When curl is told to use the Certificate Status Request TLS extension, often referred to as OCSP stapling, to verify that the server certificate is valid, it might fail to detect some OCSP problems and instead wrongly consider the response as fine. If the returned status reports another error than 'revoked' (like for example 'unauthorized') it is not treated as a bad certficate.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 curl.

      -

      References

      - +

      MPL-2.0 license


    -
    -

    CVE-2023-7008

    +
    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - systemd/libsystemd0 + github.com/gosimple/slug
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and systemd/libsystemd0@249.11-0ubuntu3.12 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
    @@ -2399,27 +1980,212 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + github.com/argoproj/argo-cd/v2@* - systemd/libsystemd0@249.11-0ubuntu3.12 + github.com/gosimple/slug@v1.13.1
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - apt@2.4.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    CVE-2023-4039

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + gcc-12/libstdc++6 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + apt@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + apt@2.4.13 + + apt/libapt-pkg6.0@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream gcc-12 package and not the gcc-12 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    DISPUTEDA failure in the -fstack-protector feature in GCC-based toolchains + that target AArch64 allows an attacker to exploit an existing buffer + overflow in dynamically-sized local variables in your application + without this being detected. This stack-protector failure only applies + to C99-style dynamically-sized local variables or those created using + alloca(). The stack-protector operates as intended for statically-sized + local variables.

    +

    The default behavior when the stack-protector + detects an overflow is to terminate your application, resulting in + controlled loss of availability. An attacker who can exploit a buffer + overflow without triggering the stack-protector might be able to change + program flow control to cause an uncontrolled loss of availability or to + go further and affect confidentiality or integrity. NOTE: The GCC project argues that this is a missed hardening bug and not a vulnerability by itself.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 gcc-12.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-7008

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + systemd/libsystemd0 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and systemd/libsystemd0@249.11-0ubuntu3.12 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + systemd/libsystemd0@249.11-0ubuntu3.12 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + apt@2.4.13 + + systemd/libsystemd0@249.11-0ubuntu3.12 + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps/libprocps8@2:3.3.17-6ubuntu2.1 @@ -2430,7 +2196,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 util-linux@2.37.2-4ubuntu3.4 @@ -2441,7 +2207,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 util-linux/bsdutils@1:2.37.2-4ubuntu3.4 @@ -2452,11 +2218,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -2465,7 +2231,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 systemd/libudev1@249.11-0ubuntu3.12 @@ -2474,7 +2240,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 libfido2/libfido2-1@1.10.0-1 @@ -2485,7 +2251,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 util-linux@2.37.2-4ubuntu3.4 @@ -2496,11 +2262,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 systemd/libudev1@249.11-0ubuntu3.12 @@ -2522,14 +2288,15 @@

      Remediation

      References


      @@ -2551,7 +2318,7 @@

      Arbitrary Code Injection

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -2564,7 +2331,7 @@

        Arbitrary Code Injection

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and shadow/passwd@1:4.8.1-2ubuntu2.2 + docker-image|quay.io/argoproj/argocd@v2.11.12 and shadow/passwd@1:4.8.1-2ubuntu2.2
      @@ -2577,7 +2344,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 shadow/passwd@1:4.8.1-2ubuntu2.2 @@ -2586,7 +2353,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -2597,7 +2364,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -2608,7 +2375,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 shadow/login@1:4.8.1-2ubuntu2.2 @@ -2655,7 +2422,7 @@

        Uncontrolled Recursion

        • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -2668,7 +2435,7 @@

          Uncontrolled Recursion

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
        @@ -2681,7 +2448,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 @@ -2690,7 +2457,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 grep@3.7-1build1 @@ -2732,77 +2499,7 @@

          References

    -

    Release of Invalid Pointer or Reference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    Double Free

    +

    Integer Overflow or Wraparound

    @@ -2813,7 +2510,7 @@

    Double Free

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2821,12 +2518,12 @@

      Double Free

    • Vulnerable module: - patch + pcre2/libpcre2-8-0
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.11.12 and pcre2/libpcre2-8-0@10.39-3ubuntu0.1
    @@ -2839,9 +2536,9 @@

    Detailed paths

    -

    CVE-2024-2511

    +

    Release of Invalid Pointer or Reference

    @@ -2888,535 +2581,105 @@

    CVE-2024-2511

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    Issue summary: Some non-default TLS server configurations can cause unbounded - memory growth when processing TLSv1.3 sessions

    -

    Impact summary: An attacker may exploit certain server configurations to trigger - unbounded memory growth that would lead to a Denial of Service

    -

    This problem can occur in TLSv1.3 if the non-default SSL_OP_NO_TICKET option is - being used (but not if early_data support is also configured and the default - anti-replay protection is in use). In this case, under certain conditions, the - session cache can get into an incorrect state and it will fail to flush properly - as it fills. The session cache will continue to grow in an unbounded manner. A - malicious client could deliberately create the scenario for this failure to - force a Denial of Service. It may also happen by accident in normal operation.

    -

    This issue only affects TLS servers supporting TLSv1.3. It does not affect TLS - clients.

    -

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue. OpenSSL - 1.0.2 is also not affected by this issue.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.17 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4603

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DSA keys or parameters may be very - slow.

    -

    Impact summary: Applications that use the functions EVP_PKEY_param_check() - or EVP_PKEY_public_check() to check a DSA public key or DSA parameters may - experience long delays. Where the key or parameters that are being checked - have been obtained from an untrusted source this may lead to a Denial of - Service.

    -

    The functions EVP_PKEY_param_check() or EVP_PKEY_public_check() perform - various checks on DSA parameters. Some of those computations take a long time - if the modulus (p parameter) is too large.

    -

    Trying to use a very large modulus is slow and OpenSSL will not allow using - public keys with a modulus which is over 10,000 bits in length for signature - verification. However the key and parameter check functions do not limit - the modulus size when performing the checks.

    -

    An application that calls EVP_PKEY_param_check() or EVP_PKEY_public_check() - and supplies a key or parameters obtained from an untrusted source could be - vulnerable to a Denial of Service attack.

    -

    These functions are not called by OpenSSL itself on untrusted DSA keys so - only applications that directly call these functions may be vulnerable.

    -

    Also vulnerable are the OpenSSL pkey and pkeyparam command line applications - when using the -check option.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.17 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.16 - - +
    • + Vulnerable module: -
    • + patch + + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and patch@2.7.6-7build2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl@3.0.2-0ubuntu1.16 + patch@2.7.6-7build2
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    Double Free

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and patch@2.7.6-7build2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    CVE-2024-5535

    +

    CVE-2024-41996

    @@ -3455,7 +2726,7 @@

    CVE-2024-5535

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3468,7 +2739,7 @@

      CVE-2024-5535

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 and openssl/libssl3@3.0.2-0ubuntu1.18
    @@ -3481,77 +2752,77 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 libfido2/libfido2-1@1.10.0-1 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - ca-certificates@20230311ubuntu0.22.04.1 + ca-certificates@20240203~22.04.1 - openssl@3.0.2-0ubuntu1.16 + openssl@3.0.2-0ubuntu1.18 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -3563,31 +2834,31 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - openssl/libssl3@3.0.2-0ubuntu1.16 + openssl/libssl3@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - openssl@3.0.2-0ubuntu1.16 + openssl@3.0.2-0ubuntu1.18
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - ca-certificates@20230311ubuntu0.22.04.1 + ca-certificates@20240203~22.04.1 - openssl@3.0.2-0ubuntu1.16 + openssl@3.0.2-0ubuntu1.18 @@ -3601,82 +2872,21 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an - empty supported client protocols buffer may cause a crash or memory contents to - be sent to the peer.

      -

      Impact summary: A buffer overread can have a range of potential consequences - such as unexpected application beahviour or a crash. In particular this issue - could result in up to 255 bytes of arbitrary private data from memory being sent - to the peer leading to a loss of confidentiality. However, only applications - that directly call the SSL_select_next_proto function with a 0 length list of - supported client protocols are affected by this issue. This would normally never - be a valid scenario and is typically not under attacker control but may occur by - accident in the case of a configuration or programming error in the calling - application.

      -

      The OpenSSL API function SSL_select_next_proto is typically used by TLS - applications that support ALPN (Application Layer Protocol Negotiation) or NPN - (Next Protocol Negotiation). NPN is older, was never standardised and - is deprecated in favour of ALPN. We believe that ALPN is significantly more - widely deployed than NPN. The SSL_select_next_proto function accepts a list of - protocols from the server and a list of protocols from the client and returns - the first protocol that appears in the server list that also appears in the - client list. In the case of no overlap between the two lists it returns the - first item in the client list. In either case it will signal whether an overlap - between the two lists was found. In the case where SSL_select_next_proto is - called with a zero length client list it fails to notice this condition and - returns the memory immediately following the client list pointer (and reports - that there was no overlap in the lists).

      -

      This function is typically called from a server side application callback for - ALPN or a client side application callback for NPN. In the case of ALPN the list - of protocols supplied by the client is guaranteed by libssl to never be zero in - length. The list of server protocols comes from the application and should never - normally be expected to be of zero length. In this case if the - SSL_select_next_proto function has been called as expected (with the list - supplied by the client passed in the client/client_len parameters), then the - application will not be vulnerable to this issue. If the application has - accidentally been configured with a zero length server list, and has - accidentally passed that zero length server list in the client/client_len - parameters, and has additionally failed to correctly handle a "no overlap" - response (which would normally result in a handshake failure in ALPN) then it - will be vulnerable to this problem.

      -

      In the case of NPN, the protocol permits the client to opportunistically select - a protocol when there is no overlap. OpenSSL returns the first client protocol - in the no overlap case in support of this. The list of client protocols comes - from the application and should never normally be expected to be of zero length. - However if the SSL_select_next_proto function is accidentally called with a - client_len of 0 then an invalid memory pointer will be returned instead. If the - application uses this output as the opportunistic protocol then the loss of - confidentiality will occur.

      -

      This issue has been assessed as Low severity because applications are most - likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not - widely used. It also requires an application configuration or programming error. - Finally, this issue would not typically be under attacker control making active - exploitation unlikely.

      -

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      -

      Due to the low severity of this issue we are not issuing new releases of - OpenSSL at this time. The fix will be included in the next releases when they - become available.

      +

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      Remediation

      -

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.17 or higher.

      +

      There is no fixed version for Ubuntu:22.04 openssl.

      References


    @@ -3692,7 +2902,7 @@

    CVE-2023-50495

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3705,7 +2915,7 @@

      CVE-2023-50495

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -3718,7 +2928,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -3727,7 +2937,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 bash@5.1-6ubuntu1.1 @@ -3738,7 +2948,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -3749,7 +2959,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 less@590-1ubuntu0.22.04.3 @@ -3760,7 +2970,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 libedit/libedit2@3.1-20210910-1build1 @@ -3771,7 +2981,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -3782,7 +2992,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -3793,7 +3003,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -3804,7 +3014,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 util-linux@2.37.2-4ubuntu3.4 @@ -3815,7 +3025,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3830,7 +3040,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3845,7 +3055,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -3854,7 +3064,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -3865,7 +3075,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3880,7 +3090,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -3889,7 +3099,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -3900,7 +3110,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -3909,7 +3119,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -3931,10 +3141,10 @@

      Remediation

      References


      @@ -3956,7 +3166,7 @@

      CVE-2023-45918

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -3969,7 +3179,7 @@

        CVE-2023-45918

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and ncurses/libtinfo6@6.3-2ubuntu0.1
      @@ -3982,7 +3192,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -3991,7 +3201,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 bash@5.1-6ubuntu1.1 @@ -4002,7 +3212,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -4013,7 +3223,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 less@590-1ubuntu0.22.04.3 @@ -4024,7 +3234,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 libedit/libedit2@3.1-20210910-1build1 @@ -4035,7 +3245,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -4046,7 +3256,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -4057,7 +3267,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -4068,7 +3278,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 util-linux@2.37.2-4ubuntu3.4 @@ -4079,7 +3289,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -4094,7 +3304,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4109,7 +3319,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -4118,7 +3328,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -4129,7 +3339,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4144,7 +3354,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -4153,7 +3363,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 procps@2:3.3.17-6ubuntu2.1 @@ -4164,7 +3374,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -4173,7 +3383,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -4189,7 +3399,7 @@

        Detailed paths

        NVD Description

        Note: Versions mentioned in the description apply only to the upstream ncurses package and not the ncurses package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

        -

        ncurses 6.4-20230610 has a NULL pointer dereference in tgetstr in tinfo/lib_termcap.c.

        +

        Rejected reason: DO NOT USE THIS CANDIDATE NUMBER. ConsultIDs: none. Reason: This candidate was withdrawn by its CNA. Further investigation showed that it was not a security issue. Notes: none.

        Remediation

        There is no fixed version for Ubuntu:22.04 ncurses.

        References

        @@ -4197,6 +3407,7 @@

        References

      • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2023-45918
      • https://lists.gnu.org/archive/html/bug-ncurses/2023-06/msg00005.html
      • https://security.netapp.com/advisory/ntap-20240315-0006/
      • +
      • https://bugzilla.redhat.com/show_bug.cgi?id=2300290#c1

      @@ -4218,7 +3429,7 @@

      Resource Exhaustion

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -4231,22 +3442,240 @@

        Resource Exhaustion

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and libzstd/libzstd1@1.4.8+dfsg-3build1 + +
      • +
      + +
      + + +

      Detailed paths

      + +
        +
      • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + libzstd/libzstd1@1.4.8+dfsg-3build1 + + + +
      • +
      + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream libzstd package and not the libzstd package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in zstd v1.4.10, where an attacker can supply empty string as an argument to the command line tool to cause buffer overrun.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 libzstd.

    +

    References

    + + +
    + + + +
    +
    +

    Information Exposure

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libgcrypt20 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.12 and libgcrypt20@1.9.4-3ubuntu3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + apt@2.4.13 + + apt/libapt-pkg6.0@2.4.13 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + apt@2.4.13 + + gnupg2/gpgv@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + -
    • -
    + +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + -

    Detailed paths

    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + libgcrypt20@1.9.4-3ubuntu3 + + -
  • @@ -4295,7 +3720,7 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -4308,7 +3733,7 @@

      Integer Overflow or Wraparound

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
    @@ -4321,16 +3746,16 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4342,16 +3767,16 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4363,27 +3788,27 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4395,64 +3820,64 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4464,16 +3889,16 @@

      Detailed paths

      libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4519,7 +3944,7 @@

      CVE-2024-26461

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -4532,7 +3957,7 @@

        CVE-2024-26461

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
      @@ -4545,16 +3970,16 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4566,16 +3991,16 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4587,27 +4012,27 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4619,64 +4044,64 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4688,16 +4113,16 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4740,7 +4165,7 @@

        CVE-2024-26458

        • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -4753,7 +4178,7 @@

          CVE-2024-26458

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.12 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
        @@ -4766,16 +4191,16 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4787,16 +4212,16 @@

          Detailed paths

          libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4808,27 +4233,27 @@

          Detailed paths

          libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4840,64 +4265,64 @@

          Detailed paths

          libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 adduser@3.118ubuntu5 @@ -4909,16 +4334,16 @@

          Detailed paths

          libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4961,7 +4386,7 @@

          Out-of-bounds Write

          • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -4974,7 +4399,7 @@

            Out-of-bounds Write

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.11.12 and gnupg2/gpgv@2.2.27-3ubuntu2.1
          @@ -4987,7 +4412,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -4996,9 +4421,9 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + apt@2.4.13 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -5007,7 +4432,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5018,7 +4443,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -5029,7 +4454,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -5040,7 +4465,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5053,7 +4478,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5066,7 +4491,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -5075,7 +4500,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5086,7 +4511,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5099,7 +4524,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 @@ -5108,7 +4533,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5119,7 +4544,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 @@ -5128,7 +4553,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5139,7 +4564,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -5148,7 +4573,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5159,7 +4584,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5172,7 +4597,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5185,7 +4610,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg-agent@2.2.27-3ubuntu2.1 @@ -5194,7 +4619,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5205,7 +4630,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5218,7 +4643,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5231,7 +4656,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 @@ -5240,7 +4665,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5251,7 +4676,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 @@ -5260,7 +4685,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5271,7 +4696,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gpgsm@2.2.27-3ubuntu2.1 @@ -5280,7 +4705,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5291,7 +4716,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5340,7 +4765,7 @@

            Allocation of Resources Without Limits or Throttling

          • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -5353,7 +4778,7 @@

            Allocation of Resources Without Limits or Throttling

            Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and glibc/libc-bin@2.35-0ubuntu3.8 + docker-image|quay.io/argoproj/argocd@v2.11.12 and glibc/libc-bin@2.35-0ubuntu3.8
          @@ -5366,7 +4791,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 glibc/libc-bin@2.35-0ubuntu3.8 @@ -5375,7 +4800,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 glibc/libc6@2.35-0ubuntu3.8 @@ -5408,6 +4833,144 @@

            References

            More about this vulnerability

    +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt/v4 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt/v4@v4.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/golang-jwt/jwt/v4@v4.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt@v3.2.2+incompatible + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/golang-jwt/jwt@v3.2.2+incompatible + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    A fix was pushed into the master branch but not yet published.

    +

    References

    + + +
    + + +

    Improper Input Validation

    @@ -5421,7 +4984,7 @@

    Improper Input Validation

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -5435,7 +4998,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others + docker-image|quay.io/argoproj/argocd@v2.11.12, git@1:2.34.1-1ubuntu1.11 and others
    @@ -5447,7 +5010,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 @@ -5458,7 +5021,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git@1:2.34.1-1ubuntu1.11 @@ -5467,7 +5030,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 git-lfs@3.0.2-1ubuntu0.2 @@ -5514,7 +5077,7 @@

      Uncontrolled Recursion

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -5527,7 +5090,7 @@

        Uncontrolled Recursion

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + docker-image|quay.io/argoproj/argocd@v2.11.12 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
      @@ -5540,7 +5103,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -5549,9 +5112,9 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + apt@2.4.13 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -5560,11 +5123,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -5573,7 +5136,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 @@ -5582,7 +5145,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -5616,6 +5179,101 @@

        References

        More about this vulnerability

    +
    +
    +

    Insufficient Comparison

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.11.12, git@1:2.34.1-1ubuntu1.11 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.12 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    When curl is asked to use HSTS, the expiry time for a subdomain might + overwrite a parent domain's cache entry, making it end sooner or later than + otherwise intended.

    +

    This affects curl using applications that enable HSTS and use URLs with the + insecure HTTP:// scheme and perform transfers with hosts like + x.example.com as well as example.com where the first host is a subdomain + of the second host.

    +

    (The HSTS cache either needs to have been populated manually or there needs to + have been previous HTTPS accesses done as the cache needs to have entries for + the domains involved to trigger this problem.)

    +

    When x.example.com responds with Strict-Transport-Security: headers, this + bug can make the subdomain's expiry timeout bleed over and get set for the + parent domain example.com in curl's HSTS cache.

    +

    The result of a triggered bug is that HTTP accesses to example.com get + converted to HTTPS for a different period of time than what was asked for by + the origin server. If example.com for example stops supporting HTTPS at its + expiry time, curl might then fail to access http://example.com until the + (wrongly set) timeout expires. This bug can also expire the parent's entry + earlier, thus making curl inadvertently switch back to insecure HTTP earlier + than otherwise intended.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.19 or higher.

    +

    References

    + + +
    + + +

    Improper Input Validation

    @@ -5629,7 +5287,7 @@

    Improper Input Validation

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.12/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -5642,7 +5300,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and coreutils@8.32-4.1ubuntu1.2 + docker-image|quay.io/argoproj/argocd@v2.11.12 and coreutils@8.32-4.1ubuntu1.2
    @@ -5655,7 +5313,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.12 coreutils@8.32-4.1ubuntu1.2 diff --git a/docs/snyk/v2.10.16/redis_7.0.15-alpine.html b/docs/snyk/v2.11.12/redis_7.0.15-alpine.html similarity index 52% rename from docs/snyk/v2.10.16/redis_7.0.15-alpine.html rename to docs/snyk/v2.11.12/redis_7.0.15-alpine.html index dace95d6e4de1..18fb60b5c1b68 100644 --- a/docs/snyk/v2.10.16/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.11.12/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

      Snyk test report

      -

      September 15th 2024, 12:26:27 am (UTC+00:00)

      +

      December 15th 2024, 12:29:49 am (UTC+00:00)

      Scanned the following paths: @@ -467,8 +467,8 @@

      Snyk test report

      -
      0 known vulnerabilities
      -
      0 vulnerable dependency paths
      +
      1 known vulnerabilities
      +
      9 vulnerable dependency paths
      18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.11.8/argocd-test.html b/docs/snyk/v2.11.8/argocd-test.html deleted file mode 100644 index c47bbee9440bb..0000000000000 --- a/docs/snyk/v2.11.8/argocd-test.html +++ /dev/null @@ -1,3816 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    September 15th 2024, 12:23:42 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • -
    • /argo-cd/ui/yarn.lock (yarn)
    • -
    -
    - -
    -
    6 known vulnerabilities
    -
    157 vulnerable dependency paths
    -
    2041 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.26.11 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/soheilhy/cmux@0.1.5 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.21.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.46.1 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/apps/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/rbac/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/errors@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/equality@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.59.0 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.59.0 - - google.golang.org/grpc/health/grpc_health_v1@1.59.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.26.11 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.26.11 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/scheme@0.14.7 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/resource@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/util/retry@0.26.11 - - k8s.io/apimachinery/pkg/api/errors@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/managedfields@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/portforward@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.26.11 - - k8s.io/apimachinery/pkg/api/equality@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/validation@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.26.11 - - k8s.io/client-go/testing@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.14.7 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/auth@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.26.11 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.26.11 - - k8s.io/client-go/tools/reference@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/apps/v1@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.26.11 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.26.11 - - k8s.io/client-go/tools/remotecommand@0.26.11 - - k8s.io/client-go/transport/spdy@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - k8s.io/client-go/transport@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - k8s.io/client-go/listers/core/v1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.26.11 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 - - k8s.io/client-go/applyconfigurations/storage/v1beta1@0.26.11 - - k8s.io/client-go/applyconfigurations/meta/v1@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.14.7 - - k8s.io/client-go/tools/cache@0.26.11 - - k8s.io/client-go/tools/pager@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb - - k8s.io/kubectl/pkg/cmd/util@0.26.11 - - k8s.io/kubectl/pkg/validation@0.26.11 - - k8s.io/cli-runtime/pkg/resource@0.26.11 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.14.7 - - k8s.io/apimachinery/pkg/runtime/serializer@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - k8s.io/client-go/tools/clientcmd@0.26.11 - - k8s.io/client-go/tools/clientcmd/api/latest@0.26.11 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.26.11 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb - - k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 - - k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.26.11 - - k8s.io/api/storage/v1alpha1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/manager@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.14.7 - - k8s.io/client-go/tools/leaderelection@0.26.11 - - k8s.io/client-go/tools/leaderelection/resourcelock@0.26.11 - - k8s.io/client-go/rest@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - google.golang.org/api/chat/v1@0.132.0 - - google.golang.org/api/transport/http@0.132.0 - - google.golang.org/api/option@0.132.0 - - google.golang.org/grpc@1.59.0 - - google.golang.org/grpc/internal/transport@1.59.0 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb - - k8s.io/kubectl/pkg/util/openapi@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.14.7 - - k8s.io/client-go/restmapper@0.26.11 - - k8s.io/client-go/discovery@0.26.11 - - k8s.io/client-go/kubernetes/scheme@0.26.11 - - k8s.io/api/storage/v1beta1@0.26.11 - - k8s.io/api/core/v1@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.14.7 - - sigs.k8s.io/controller-runtime/pkg/client@0.14.7 - - k8s.io/client-go/dynamic@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 - - k8s.io/apimachinery/pkg/watch@0.26.11 - - k8s.io/apimachinery/pkg/util/net@0.26.11 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Regular Expression Denial of Service (ReDoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - path-to-regexp -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, react-router@4.3.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - argo-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

    -

    Note: - Version 0.1.10 is patched to mitigate this but is also vulnerable if custom regular expressions are used. Due to the existence of this attack vector, the Snyk security team have decided to err on the side of caution in considering the very widely-used v0 branch vulnerable, while the 8.0.0 release has completely eliminated the vulnerable functionality.

    -

    Workaround

    -

    This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

    -

    PoC

    -
    /a${'-a'.repeat(8_000)}/a
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    -

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    -

    Let’s take the following regular expression as an example:

    -
    regex = /A(B|C+)+D/
    -        
    -

    This regular expression accomplishes the following:

    -
      -
    • A The string must start with the letter 'A'
    • -
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • -
    • D Finally, we ensure this section of the string ends with a 'D'
    • -
    -

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    -

    It most cases, it doesn't take very long for a regex engine to find a match:

    -
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    -        0.04s user 0.01s system 95% cpu 0.052 total
    -        
    -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    -        1.79s user 0.02s system 99% cpu 1.812 total
    -        
    -

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    -

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    -

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    -
      -
    1. CCC
    2. -
    3. CC+C
    4. -
    5. C+CC
    6. -
    7. C+C+C.
    8. -
    -

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    -

    From there, the number of steps the engine must use to validate a string just continues to grow.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    -

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    -

    Remediation

    -

    Upgrade path-to-regexp to version 8.0.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/rs/cors -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - github.com/rs/cors@1.9.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    -

    PoC

    -
    
    -        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    -            resps := makeFakeResponses(b.N)
    -            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    -            req.Header.Add(headerOrigin, dummyOrigin)
    -            req.Header.Add(headerACRM, http.MethodGet)
    -            req.Header[headerACRH] = adversarialACRH
    -            handler := Default().Handler(testHandler)
    -        
    -            b.ReportAllocs()
    -            b.ResetTimer()
    -            for i := 0; i < b.N; i++ {
    -                handler.ServeHTTP(resps[i], req)
    -            }
    -        }
    -        
    -        var adversarialACRH []string
    -        
    -        func init() { // populates adversarialACRH
    -            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    -            commas := strings.Repeat(",", n)
    -            res := make([]string, n)
    -            for i := range res {
    -                res[i] = commas
    -            }
    -            adversarialACRH = res
    -        }
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    -

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    -

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    -

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    -

    Two common types of DoS vulnerabilities:

    -
      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      -
    • -
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      -
    • -
    -

    Remediation

    -

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Insertion of Sensitive Information into Log File

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/xanzy/go-gitlab@0.91.1 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#f48567108f01 - - github.com/argoproj/notifications-engine/pkg/services@#f48567108f01 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/Azure/azure-sdk-for-go/sdk/azidentity -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    -

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    -

    Notes:

    -
      -
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      -
    2. -
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      -
    4. -
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      -
    6. -
    7. The vulnerability exists in the following credential types:

      -
    8. -
    -

    ManagedIdentityApplication (.NET)

    -

    ManagedIdentityApplication (Java)

    -

    ManagedIdentityApplication (Node.js)

    -

    Remediation

    -

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Template Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - dompurify -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - redoc@2.0.0-rc.64 - - dompurify@2.3.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    -

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    -

    PoC

    -
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    -        
    -

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html deleted file mode 100644 index af51282d2e037..0000000000000 --- a/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html +++ /dev/null @@ -1,2628 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    September 15th 2024, 12:23:48 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex (apk)
    • -
    • ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3//usr/local/bin/gomplate (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.38.0/dexidp/dex//usr/local/bin/dex (gomodules)
    • -
    -
    - -
    -
    18 known vulnerabilities
    -
    85 vulnerable dependency paths
    -
    829 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.19.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - golang.org/x/net/http2@v0.19.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.20.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: The POLY1305 MAC (message authentication code) implementation - contains a bug that might corrupt the internal state of applications running - on PowerPC CPU based platforms if the CPU provides vector instructions.

    -

    Impact summary: If an attacker can influence whether the POLY1305 MAC - algorithm is used, the application state might be corrupted with various - application dependent consequences.

    -

    The POLY1305 MAC (message authentication code) implementation in OpenSSL for - PowerPC CPUs restores the contents of vector registers in a different order - than they are saved. Thus the contents of some of these vector registers - are corrupted when returning to the caller. The vulnerable code is used only - on newer PowerPC processors supporting the PowerISA 2.07 instructions.

    -

    The consequences of this kind of internal application state corruption can - be various - from no consequences, if the calling application does not - depend on the contents of non-volatile XMM registers at all, to the worst - consequences, where the attacker could get complete control of the application - process. However unless the compiler uses the vector registers for storing - pointers, the most likely consequence, if any, would be an incorrect result - of some application dependent calculations or a crash leading to a denial of - service.

    -

    The POLY1305 MAC algorithm is most frequently used as part of the - CHACHA20-POLY1305 AEAD (authenticated encryption with associated data) - algorithm. The most common usage of this AEAD cipher is with TLS protocol - versions 1.2 and 1.3. If this cipher is enabled on the server a malicious - client can influence whether this AEAD cipher is used. This implies that - TLS server applications using OpenSSL can be potentially impacted. However - we are currently not aware of any concrete application that would be affected - by this issue therefore we consider this a Low severity security issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.4-r3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-0727

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Processing a maliciously formatted PKCS12 file may lead OpenSSL - to crash leading to a potential Denial of Service attack

    -

    Impact summary: Applications loading files in the PKCS12 format from untrusted - sources might terminate abruptly.

    -

    A file in PKCS12 format can contain certificates and keys and may come from an - untrusted source. The PKCS12 specification allows certain fields to be NULL, but - OpenSSL does not correctly check for this case. This can lead to a NULL pointer - dereference that results in OpenSSL crashing. If an application processes PKCS12 - files from an untrusted source using the OpenSSL APIs then that application will - be vulnerable to this issue.

    -

    OpenSSL APIs that are vulnerable to this are: PKCS12_parse(), - PKCS12_unpack_p7data(), PKCS12_unpack_p7encdata(), PKCS12_unpack_authsafes() - and PKCS12_newpass().

    -

    We have also fixed a similar issue in SMIME_write_PKCS7(). However since this - function is related to writing data we do not consider it security significant.

    -

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.4-r5 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Infinite loop

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/protobuf/internal/encoding/json -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.31.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/internal/encoding/json@v1.31.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/internal/encoding/json@v1.32.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Stack-based Buffer Overflow

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/protobuf/encoding/protojson -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Stack-based Buffer Overflow when processing input that uses pathologically deep nesting.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.32.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Infinite loop

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/protobuf/encoding/protojson -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.32.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Insertion of Sensitive Information into Log File

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-retryablehttp@v0.7.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Improper Handling of Highly Compressed Data (Data Amplification)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-jose/go-jose/v3@v3.0.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

    -

    Remediation

    -

    Upgrade Alpine:3.19 busybox to version 1.36.1-r16 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    -

    Remediation

    -

    Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    -

    Remediation

    -

    Upgrade Alpine:3.19 busybox to version 1.36.1-r19 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - busybox/busybox@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

    -

    Remediation

    -

    Upgrade Alpine:3.19 busybox to version 1.36.1-r17 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-6237

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long invalid RSA public keys may take - a long time.

    -

    Impact summary: Applications that use the function EVP_PKEY_public_check() - to check RSA public keys may experience long delays. Where the key that - is being checked has been obtained from an untrusted source this may lead - to a Denial of Service.

    -

    When function EVP_PKEY_public_check() is called on RSA public keys, - a computation is done to confirm that the RSA modulus, n, is composite. - For valid RSA keys, n is a product of two or more large primes and this - computation completes quickly. However, if n is an overly large prime, - then this computation would take a long time.

    -

    An application that calls EVP_PKEY_public_check() and supplies an RSA key - obtained from an untrusted source could be vulnerable to a Denial of Service - attack.

    -

    The function EVP_PKEY_public_check() is not called from other OpenSSL - functions however it is called from the OpenSSL pkey command line - application. For that reason that application is also vulnerable if used - with the '-pubin' and '-check' options on untrusted data.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.4-r4 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-2511

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Some non-default TLS server configurations can cause unbounded - memory growth when processing TLSv1.3 sessions

    -

    Impact summary: An attacker may exploit certain server configurations to trigger - unbounded memory growth that would lead to a Denial of Service

    -

    This problem can occur in TLSv1.3 if the non-default SSL_OP_NO_TICKET option is - being used (but not if early_data support is also configured and the default - anti-replay protection is in use). In this case, under certain conditions, the - session cache can get into an incorrect state and it will fail to flush properly - as it fills. The session cache will continue to grow in an unbounded manner. A - malicious client could deliberately create the scenario for this failure to - force a Denial of Service. It may also happen by accident in normal operation.

    -

    This issue only affects TLS servers supporting TLSv1.3. It does not affect TLS - clients.

    -

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue. OpenSSL - 1.0.2 is also not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.4-r6 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4603

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DSA keys or parameters may be very - slow.

    -

    Impact summary: Applications that use the functions EVP_PKEY_param_check() - or EVP_PKEY_public_check() to check a DSA public key or DSA parameters may - experience long delays. Where the key or parameters that are being checked - have been obtained from an untrusted source this may lead to a Denial of - Service.

    -

    The functions EVP_PKEY_param_check() or EVP_PKEY_public_check() perform - various checks on DSA parameters. Some of those computations take a long time - if the modulus (p parameter) is too large.

    -

    Trying to use a very large modulus is slow and OpenSSL will not allow using - public keys with a modulus which is over 10,000 bits in length for signature - verification. However the key and parameter check functions do not limit - the modulus size when performing the checks.

    -

    An application that calls EVP_PKEY_param_check() or EVP_PKEY_public_check() - and supplies a key or parameters obtained from an untrusted source could be - vulnerable to a Denial of Service attack.

    -

    These functions are not called by OpenSSL itself on untrusted DSA keys so - only applications that directly call these functions may be vulnerable.

    -

    Also vulnerable are the OpenSSL pkey and pkeyparam command line applications - when using the -check option.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.5-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-5535

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an - empty supported client protocols buffer may cause a crash or memory contents to - be sent to the peer.

    -

    Impact summary: A buffer overread can have a range of potential consequences - such as unexpected application beahviour or a crash. In particular this issue - could result in up to 255 bytes of arbitrary private data from memory being sent - to the peer leading to a loss of confidentiality. However, only applications - that directly call the SSL_select_next_proto function with a 0 length list of - supported client protocols are affected by this issue. This would normally never - be a valid scenario and is typically not under attacker control but may occur by - accident in the case of a configuration or programming error in the calling - application.

    -

    The OpenSSL API function SSL_select_next_proto is typically used by TLS - applications that support ALPN (Application Layer Protocol Negotiation) or NPN - (Next Protocol Negotiation). NPN is older, was never standardised and - is deprecated in favour of ALPN. We believe that ALPN is significantly more - widely deployed than NPN. The SSL_select_next_proto function accepts a list of - protocols from the server and a list of protocols from the client and returns - the first protocol that appears in the server list that also appears in the - client list. In the case of no overlap between the two lists it returns the - first item in the client list. In either case it will signal whether an overlap - between the two lists was found. In the case where SSL_select_next_proto is - called with a zero length client list it fails to notice this condition and - returns the memory immediately following the client list pointer (and reports - that there was no overlap in the lists).

    -

    This function is typically called from a server side application callback for - ALPN or a client side application callback for NPN. In the case of ALPN the list - of protocols supplied by the client is guaranteed by libssl to never be zero in - length. The list of server protocols comes from the application and should never - normally be expected to be of zero length. In this case if the - SSL_select_next_proto function has been called as expected (with the list - supplied by the client passed in the client/client_len parameters), then the - application will not be vulnerable to this issue. If the application has - accidentally been configured with a zero length server list, and has - accidentally passed that zero length server list in the client/client_len - parameters, and has additionally failed to correctly handle a "no overlap" - response (which would normally result in a handshake failure in ALPN) then it - will be vulnerable to this problem.

    -

    In the case of NPN, the protocol permits the client to opportunistically select - a protocol when there is no overlap. OpenSSL returns the first client protocol - in the no overlap case in support of this. The list of client protocols comes - from the application and should never normally be expected to be of zero length. - However if the SSL_select_next_proto function is accidentally called with a - client_len of 0 then an invalid memory pointer will be returned instead. If the - application uses this output as the opportunistic protocol then the loss of - confidentiality will occur.

    -

    This issue has been assessed as Low severity because applications are most - likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not - widely used. It also requires an application configuration or programming error. - Finally, this issue would not typically be under attacker control making active - exploitation unlikely.

    -

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Due to the low severity of this issue we are not issuing new releases of - OpenSSL at this time. The fix will be included in the next releases when they - become available.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    - -
    - - - -
    -
    -

    CVE-2024-6119

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.19 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 - - busybox/ssl_client@1.36.1-r15 - - openssl/libssl3@3.1.4-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.19 relevant fixed versions and status.

    -

    Issue summary: Applications performing certificate name checks (e.g., TLS - clients checking server certificates) may attempt to read an invalid memory - address resulting in abnormal termination of the application process.

    -

    Impact summary: Abnormal termination of an application can a cause a denial of - service.

    -

    Applications performing certificate name checks (e.g., TLS clients checking - server certificates) may attempt to read an invalid memory address when - comparing the expected name with an otherName subject alternative name of an - X.509 certificate. This may result in an exception that terminates the - application program.

    -

    Note that basic certificate chain validation (signatures, dates, ...) is not - affected, the denial of service can occur only when the application also - specifies an expected DNS name, Email address or IP address.

    -

    TLS servers rarely solicit client certificates, and even when they do, they - generally don't perform a name check against a reference identifier (expected - identity), but rather extract the presented identity after checking the - certificate chain. So TLS servers are generally not affected and the severity - of the issue is Moderate.

    -

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.7-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html b/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html deleted file mode 100644 index ce97669944805..0000000000000 --- a/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html +++ /dev/null @@ -1,2741 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    September 15th 2024, 12:23:53 am (UTC+00:00)

    -
    -
    - Scanned the following path: -
      -
    • haproxy:2.6.14-alpine (apk)
    • -
    -
    - -
    -
    14 known vulnerabilities
    -
    110 vulnerable dependency paths
    -
    18 dependencies
    -
    -
    -
    -
    -
    - - - - - - - -
    Project docker-image|haproxy
    Path haproxy:2.6.14-alpine
    Package Manager apk
    -
    -
    -
    -
    -

    CVE-2023-5363

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: A bug has been identified in the processing of key and - initialisation vector (IV) lengths. This can lead to potential truncation - or overruns during the initialisation of some symmetric ciphers.

    -

    Impact summary: A truncation in the IV can result in non-uniqueness, - which could result in loss of confidentiality for some cipher modes.

    -

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or - EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after - the key and IV have been established. Any alterations to the key length, - via the "keylen" parameter or the IV length, via the "ivlen" parameter, - within the OSSL_PARAM array will not take effect as intended, potentially - causing truncation or overreading of these values. The following ciphers - and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    -

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in - loss of confidentiality. For example, when following NIST's SP 800-38D - section 8.2.1 guidance for constructing a deterministic IV for AES in - GCM mode, truncation of the counter portion could lead to IV reuse.

    -

    Both truncations and overruns of the key and overruns of the IV will - produce incorrect results and could, in some cases, trigger a memory - exception. However, these issues are not currently assessed as security - critical.

    -

    Changing the key and/or IV lengths is not considered to be a common operation - and the vulnerable API was recently introduced. Furthermore it is likely that - application developers will have spotted this problem during testing since - decryption would fail unless both peers in the communication were similarly - vulnerable. For these reasons we expect the probability of an application being - vulnerable to this to be quite low. However if an application is vulnerable then - this issue is considered very serious. For these reasons we have assessed this - issue as Moderate severity overall.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because - the issue lies outside of the FIPS provider boundary.

    -

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Improper Check for Unusual or Exceptional Conditions

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Generating excessively long X9.42 DH keys or checking - excessively long X9.42 DH keys or parameters may be very slow.

    -

    Impact summary: Applications that use the functions DH_generate_key() to - generate an X9.42 DH key may experience long delays. Likewise, applications - that use DH_check_pub_key(), DH_check_pub_key_ex() or EVP_PKEY_public_check() - to check an X9.42 DH key or X9.42 DH parameters may experience long delays. - Where the key or parameters that are being checked have been obtained from - an untrusted source this may lead to a Denial of Service.

    -

    While DH_check() performs all the necessary checks (as of CVE-2023-3817), - DH_check_pub_key() doesn't make any of these checks, and is therefore - vulnerable for excessively large P and Q parameters.

    -

    Likewise, while DH_generate_key() performs a check for an excessively large - P, it doesn't check for an excessively large Q.

    -

    An application that calls DH_generate_key() or DH_check_pub_key() and - supplies a key or parameters obtained from an untrusted source could be - vulnerable to a Denial of Service attack.

    -

    DH_generate_key() and DH_check_pub_key() are also called by a number of - other OpenSSL functions. An application calling any of those other - functions may similarly be affected. The other functions affected by this - are DH_check_pub_key_ex(), EVP_PKEY_public_check(), and EVP_PKEY_generate().

    -

    Also vulnerable are the OpenSSL pkey command line application when using the - "-pubcheck" option, as well as the OpenSSL genpkey command line application.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r1 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: The POLY1305 MAC (message authentication code) implementation - contains a bug that might corrupt the internal state of applications running - on PowerPC CPU based platforms if the CPU provides vector instructions.

    -

    Impact summary: If an attacker can influence whether the POLY1305 MAC - algorithm is used, the application state might be corrupted with various - application dependent consequences.

    -

    The POLY1305 MAC (message authentication code) implementation in OpenSSL for - PowerPC CPUs restores the contents of vector registers in a different order - than they are saved. Thus the contents of some of these vector registers - are corrupted when returning to the caller. The vulnerable code is used only - on newer PowerPC processors supporting the PowerISA 2.07 instructions.

    -

    The consequences of this kind of internal application state corruption can - be various - from no consequences, if the calling application does not - depend on the contents of non-volatile XMM registers at all, to the worst - consequences, where the attacker could get complete control of the application - process. However unless the compiler uses the vector registers for storing - pointers, the most likely consequence, if any, would be an incorrect result - of some application dependent calculations or a crash leading to a denial of - service.

    -

    The POLY1305 MAC algorithm is most frequently used as part of the - CHACHA20-POLY1305 AEAD (authenticated encryption with associated data) - algorithm. The most common usage of this AEAD cipher is with TLS protocol - versions 1.2 and 1.3. If this cipher is enabled on the server a malicious - client can influence whether this AEAD cipher is used. This implies that - TLS server applications using OpenSSL can be potentially impacted. However - we are currently not aware of any concrete application that would be affected - by this issue therefore we consider this a Low severity security issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-0727

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Processing a maliciously formatted PKCS12 file may lead OpenSSL - to crash leading to a potential Denial of Service attack

    -

    Impact summary: Applications loading files in the PKCS12 format from untrusted - sources might terminate abruptly.

    -

    A file in PKCS12 format can contain certificates and keys and may come from an - untrusted source. The PKCS12 specification allows certain fields to be NULL, but - OpenSSL does not correctly check for this case. This can lead to a NULL pointer - dereference that results in OpenSSL crashing. If an application processes PKCS12 - files from an untrusted source using the OpenSSL APIs then that application will - be vulnerable to this issue.

    -

    OpenSSL APIs that are vulnerable to this are: PKCS12_parse(), - PKCS12_unpack_p7data(), PKCS12_unpack_p7encdata(), PKCS12_unpack_authsafes() - and PKCS12_newpass().

    -

    We have also fixed a similar issue in SMIME_write_PKCS7(). However since this - function is related to writing data we do not consider it security significant.

    -

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r5 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

    -

    Remediation

    -

    Upgrade Alpine:3.18 busybox to version 1.36.1-r6 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

    -

    Remediation

    -

    Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    -

    Remediation

    -

    Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - busybox/busybox@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r2 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    -

    Remediation

    -

    Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-6237

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long invalid RSA public keys may take - a long time.

    -

    Impact summary: Applications that use the function EVP_PKEY_public_check() - to check RSA public keys may experience long delays. Where the key that - is being checked has been obtained from an untrusted source this may lead - to a Denial of Service.

    -

    When function EVP_PKEY_public_check() is called on RSA public keys, - a computation is done to confirm that the RSA modulus, n, is composite. - For valid RSA keys, n is a product of two or more large primes and this - computation completes quickly. However, if n is an overly large prime, - then this computation would take a long time.

    -

    An application that calls EVP_PKEY_public_check() and supplies an RSA key - obtained from an untrusted source could be vulnerable to a Denial of Service - attack.

    -

    The function EVP_PKEY_public_check() is not called from other OpenSSL - functions however it is called from the OpenSSL pkey command line - application. For that reason that application is also vulnerable if used - with the '-pubin' and '-check' options on untrusted data.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r4 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-2511

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Some non-default TLS server configurations can cause unbounded - memory growth when processing TLSv1.3 sessions

    -

    Impact summary: An attacker may exploit certain server configurations to trigger - unbounded memory growth that would lead to a Denial of Service

    -

    This problem can occur in TLSv1.3 if the non-default SSL_OP_NO_TICKET option is - being used (but not if early_data support is also configured and the default - anti-replay protection is in use). In this case, under certain conditions, the - session cache can get into an incorrect state and it will fail to flush properly - as it fills. The session cache will continue to grow in an unbounded manner. A - malicious client could deliberately create the scenario for this failure to - force a Denial of Service. It may also happen by accident in normal operation.

    -

    This issue only affects TLS servers supporting TLSv1.3. It does not affect TLS - clients.

    -

    The FIPS modules in 3.2, 3.1 and 3.0 are not affected by this issue. OpenSSL - 1.0.2 is also not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.4-r6 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4603

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DSA keys or parameters may be very - slow.

    -

    Impact summary: Applications that use the functions EVP_PKEY_param_check() - or EVP_PKEY_public_check() to check a DSA public key or DSA parameters may - experience long delays. Where the key or parameters that are being checked - have been obtained from an untrusted source this may lead to a Denial of - Service.

    -

    The functions EVP_PKEY_param_check() or EVP_PKEY_public_check() perform - various checks on DSA parameters. Some of those computations take a long time - if the modulus (p parameter) is too large.

    -

    Trying to use a very large modulus is slow and OpenSSL will not allow using - public keys with a modulus which is over 10,000 bits in length for signature - verification. However the key and parameter check functions do not limit - the modulus size when performing the checks.

    -

    An application that calls EVP_PKEY_param_check() or EVP_PKEY_public_check() - and supplies a key or parameters obtained from an untrusted source could be - vulnerable to a Denial of Service attack.

    -

    These functions are not called by OpenSSL itself on untrusted DSA keys so - only applications that directly call these functions may be vulnerable.

    -

    Also vulnerable are the OpenSSL pkey and pkeyparam command line applications - when using the -check option.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.5-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-5535

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an - empty supported client protocols buffer may cause a crash or memory contents to - be sent to the peer.

    -

    Impact summary: A buffer overread can have a range of potential consequences - such as unexpected application beahviour or a crash. In particular this issue - could result in up to 255 bytes of arbitrary private data from memory being sent - to the peer leading to a loss of confidentiality. However, only applications - that directly call the SSL_select_next_proto function with a 0 length list of - supported client protocols are affected by this issue. This would normally never - be a valid scenario and is typically not under attacker control but may occur by - accident in the case of a configuration or programming error in the calling - application.

    -

    The OpenSSL API function SSL_select_next_proto is typically used by TLS - applications that support ALPN (Application Layer Protocol Negotiation) or NPN - (Next Protocol Negotiation). NPN is older, was never standardised and - is deprecated in favour of ALPN. We believe that ALPN is significantly more - widely deployed than NPN. The SSL_select_next_proto function accepts a list of - protocols from the server and a list of protocols from the client and returns - the first protocol that appears in the server list that also appears in the - client list. In the case of no overlap between the two lists it returns the - first item in the client list. In either case it will signal whether an overlap - between the two lists was found. In the case where SSL_select_next_proto is - called with a zero length client list it fails to notice this condition and - returns the memory immediately following the client list pointer (and reports - that there was no overlap in the lists).

    -

    This function is typically called from a server side application callback for - ALPN or a client side application callback for NPN. In the case of ALPN the list - of protocols supplied by the client is guaranteed by libssl to never be zero in - length. The list of server protocols comes from the application and should never - normally be expected to be of zero length. In this case if the - SSL_select_next_proto function has been called as expected (with the list - supplied by the client passed in the client/client_len parameters), then the - application will not be vulnerable to this issue. If the application has - accidentally been configured with a zero length server list, and has - accidentally passed that zero length server list in the client/client_len - parameters, and has additionally failed to correctly handle a "no overlap" - response (which would normally result in a handshake failure in ALPN) then it - will be vulnerable to this problem.

    -

    In the case of NPN, the protocol permits the client to opportunistically select - a protocol when there is no overlap. OpenSSL returns the first client protocol - in the no overlap case in support of this. The list of client protocols comes - from the application and should never normally be expected to be of zero length. - However if the SSL_select_next_proto function is accidentally called with a - client_len of 0 then an invalid memory pointer will be returned instead. If the - application uses this output as the opportunistic protocol then the loss of - confidentiality will occur.

    -

    This issue has been assessed as Low severity because applications are most - likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not - widely used. It also requires an application configuration or programming error. - Finally, this issue would not typically be under attacker control making active - exploitation unlikely.

    -

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Due to the low severity of this issue we are not issuing new releases of - OpenSSL at this time. The fix will be included in the next releases when they - become available.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.6-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.6-r0 or higher.

    - -
    - - - -
    -
    -

    CVE-2024-6119

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - busybox/ssl_client@1.36.1-r2 - - openssl/libssl3@3.1.2-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Applications performing certificate name checks (e.g., TLS - clients checking server certificates) may attempt to read an invalid memory - address resulting in abnormal termination of the application process.

    -

    Impact summary: Abnormal termination of an application can a cause a denial of - service.

    -

    Applications performing certificate name checks (e.g., TLS clients checking - server certificates) may attempt to read an invalid memory address when - comparing the expected name with an otherName subject alternative name of an - X.509 certificate. This may result in an exception that terminates the - application program.

    -

    Note that basic certificate chain validation (signatures, dates, ...) is not - affected, the denial of service can occur only when the application also - specifies an expected DNS name, Email address or IP address.

    -

    TLS servers rarely solicit client certificates, and even when they do, they - generally don't perform a name check against a reference identifier (expected - identity), but rather extract the presented identity after checking the - certificate chain. So TLS servers are generally not affected and the severity - of the issue is Moderate.

    -

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.7-r0 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.12.3/argocd-test.html b/docs/snyk/v2.12.3/argocd-test.html deleted file mode 100644 index 876ce2850c30d..0000000000000 --- a/docs/snyk/v2.12.3/argocd-test.html +++ /dev/null @@ -1,930 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    September 15th 2024, 12:21:28 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • -
    • /argo-cd/ui/yarn.lock (yarn)
    • -
    -
    - -
    -
    4 known vulnerabilities
    -
    6 vulnerable dependency paths
    -
    2061 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Regular Expression Denial of Service (ReDoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - path-to-regexp -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, react-router@4.3.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    • - Introduced through: - argo-cd-ui@1.0.0 - - argo-ui@1.0.0 - - react-router-dom@4.3.1 - - react-router@4.3.1 - - path-to-regexp@1.8.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

    -

    Note: - Version 0.1.10 is patched to mitigate this but is also vulnerable if custom regular expressions are used. Due to the existence of this attack vector, the Snyk security team have decided to err on the side of caution in considering the very widely-used v0 branch vulnerable, while the 8.0.0 release has completely eliminated the vulnerable functionality.

    -

    Workaround

    -

    This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

    -

    PoC

    -
    /a${'-a'.repeat(8_000)}/a
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    -

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    -

    Let’s take the following regular expression as an example:

    -
    regex = /A(B|C+)+D/
    -        
    -

    This regular expression accomplishes the following:

    -
      -
    • A The string must start with the letter 'A'
    • -
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • -
    • D Finally, we ensure this section of the string ends with a 'D'
    • -
    -

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    -

    It most cases, it doesn't take very long for a regex engine to find a match:

    -
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    -        0.04s user 0.01s system 95% cpu 0.052 total
    -        
    -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    -        1.79s user 0.02s system 99% cpu 1.812 total
    -        
    -

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    -

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    -

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    -
      -
    1. CCC
    2. -
    3. CC+C
    4. -
    5. C+CC
    6. -
    7. C+C+C.
    8. -
    -

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    -

    From there, the number of steps the engine must use to validate a string just continues to grow.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    -

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    -

    Remediation

    -

    Upgrade path-to-regexp to version 8.0.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/rs/cors -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - github.com/rs/cors@1.9.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    -

    PoC

    -
    
    -        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    -            resps := makeFakeResponses(b.N)
    -            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    -            req.Header.Add(headerOrigin, dummyOrigin)
    -            req.Header.Add(headerACRM, http.MethodGet)
    -            req.Header[headerACRH] = adversarialACRH
    -            handler := Default().Handler(testHandler)
    -        
    -            b.ReportAllocs()
    -            b.ResetTimer()
    -            for i := 0; i < b.N; i++ {
    -                handler.ServeHTTP(resps[i], req)
    -            }
    -        }
    -        
    -        var adversarialACRH []string
    -        
    -        func init() { // populates adversarialACRH
    -            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    -            commas := strings.Repeat(",", n)
    -            res := make([]string, n)
    -            for i := range res {
    -                res[i] = commas
    -            }
    -            adversarialACRH = res
    -        }
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    -

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    -

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    -

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    -

    Two common types of DoS vulnerabilities:

    -
      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      -
    • -
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      -
    • -
    -

    Remediation

    -

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/Azure/azure-sdk-for-go/sdk/azidentity -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    -

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    -

    Notes:

    -
      -
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      -
    2. -
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      -
    4. -
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      -
    6. -
    7. The vulnerability exists in the following credential types:

      -
    8. -
    -

    ManagedIdentityApplication (.NET)

    -

    ManagedIdentityApplication (Java)

    -

    ManagedIdentityApplication (Node.js)

    -

    Remediation

    -

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Template Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - dompurify -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - redoc@2.0.0-rc.64 - - dompurify@2.3.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    -

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    -

    PoC

    -
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    -        
    -

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.10.16/argocd-iac-install.html b/docs/snyk/v2.12.8/argocd-iac-install.html similarity index 98% rename from docs/snyk/v2.10.16/argocd-iac-install.html rename to docs/snyk/v2.12.8/argocd-iac-install.html index f962a3756de76..2cbc23395cac5 100644 --- a/docs/snyk/v2.10.16/argocd-iac-install.html +++ b/docs/snyk/v2.12.8/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:27:49 am (UTC+00:00)

    +

    December 15th 2024, 12:28:50 am (UTC+00:00)

    Scanned the following path: @@ -507,7 +507,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20895 + Line number: 21117
  • @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20580 + Line number: 20798
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20665 + Line number: 20885
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20693 + Line number: 20913
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20723 + Line number: 20943
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20741 + Line number: 20961
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20759 + Line number: 20979
  • @@ -829,7 +829,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20781 + Line number: 21001
  • @@ -881,7 +881,7 @@

    Container could be running with outdated image

  • - Line number: 21827 + Line number: 22049
  • @@ -933,7 +933,7 @@

    Container could be running with outdated image

  • - Line number: 22108 + Line number: 22348
  • @@ -991,7 +991,7 @@

    Container has no CPU limit

  • - Line number: 21388 + Line number: 21610
  • @@ -1049,7 +1049,7 @@

    Container has no CPU limit

  • - Line number: 21639 + Line number: 21861
  • @@ -1107,7 +1107,7 @@

    Container has no CPU limit

  • - Line number: 21605 + Line number: 21827
  • @@ -1165,7 +1165,7 @@

    Container has no CPU limit

  • - Line number: 21699 + Line number: 21921
  • @@ -1223,7 +1223,7 @@

    Container has no CPU limit

  • - Line number: 21798 + Line number: 22020
  • @@ -1281,7 +1281,7 @@

    Container has no CPU limit

  • - Line number: 21822 + Line number: 22044
  • @@ -1339,7 +1339,7 @@

    Container has no CPU limit

  • - Line number: 22108 + Line number: 22348
  • @@ -1397,7 +1397,7 @@

    Container has no CPU limit

  • - Line number: 21879 + Line number: 22101
  • @@ -1455,7 +1455,7 @@

    Container has no CPU limit

  • - Line number: 22193 + Line number: 22433
  • @@ -1513,7 +1513,7 @@

    Container has no CPU limit

  • - Line number: 22544 + Line number: 22784
  • @@ -1565,7 +1565,7 @@

    Container is running with multiple open ports

  • - Line number: 21619 + Line number: 21841
  • @@ -1617,7 +1617,7 @@

    Container is running without liveness probe

  • - Line number: 21388 + Line number: 21610
  • @@ -1669,7 +1669,7 @@

    Container is running without liveness probe

  • - Line number: 21605 + Line number: 21827
  • @@ -1721,7 +1721,7 @@

    Container is running without liveness probe

  • - Line number: 21798 + Line number: 22020
  • @@ -1779,7 +1779,7 @@

    Container is running without memory limit

  • - Line number: 21388 + Line number: 21610
  • @@ -1837,7 +1837,7 @@

    Container is running without memory limit

  • - Line number: 21605 + Line number: 21827
  • @@ -1895,7 +1895,7 @@

    Container is running without memory limit

  • - Line number: 21639 + Line number: 21861
  • @@ -1953,7 +1953,7 @@

    Container is running without memory limit

  • - Line number: 21699 + Line number: 21921
  • @@ -2011,7 +2011,7 @@

    Container is running without memory limit

  • - Line number: 21798 + Line number: 22020
  • @@ -2069,7 +2069,7 @@

    Container is running without memory limit

  • - Line number: 21822 + Line number: 22044
  • @@ -2127,7 +2127,7 @@

    Container is running without memory limit

  • - Line number: 22108 + Line number: 22348
  • @@ -2185,7 +2185,7 @@

    Container is running without memory limit

  • - Line number: 21879 + Line number: 22101
  • @@ -2243,7 +2243,7 @@

    Container is running without memory limit

  • - Line number: 22193 + Line number: 22433
  • @@ -2301,7 +2301,7 @@

    Container is running without memory limit

  • - Line number: 22544 + Line number: 22784
  • @@ -2357,7 +2357,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21529 + Line number: 21751
  • @@ -2413,7 +2413,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21647 + Line number: 21869
  • @@ -2469,7 +2469,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21622 + Line number: 21844
  • @@ -2525,7 +2525,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21732 + Line number: 21954
  • @@ -2581,7 +2581,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21815 + Line number: 22037
  • @@ -2637,7 +2637,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21829 + Line number: 22051
  • @@ -2693,7 +2693,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22115 + Line number: 22355
  • @@ -2749,7 +2749,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22081 + Line number: 22321
  • @@ -2805,7 +2805,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22454 + Line number: 22694
  • @@ -2861,7 +2861,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22745 + Line number: 23003
  • diff --git a/docs/snyk/v2.12.3/argocd-iac-namespace-install.html b/docs/snyk/v2.12.8/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.12.3/argocd-iac-namespace-install.html rename to docs/snyk/v2.12.8/argocd-iac-namespace-install.html index 7fbc95ed64a61..0bd319de619ab 100644 --- a/docs/snyk/v2.12.3/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.12.8/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:23:29 am (UTC+00:00)

    +

    December 15th 2024, 12:28:59 am (UTC+00:00)

    Scanned the following path: @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 2050 + Line number: 2068
  • diff --git a/docs/snyk/v2.12.8/argocd-test.html b/docs/snyk/v2.12.8/argocd-test.html new file mode 100644 index 0000000000000..9769ab54cf9c5 --- /dev/null +++ b/docs/snyk/v2.12.8/argocd-test.html @@ -0,0 +1,2022 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:26:45 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/ui/yarn.lock (yarn)
    • +
    +
    + +
    +
    12 known vulnerabilities
    +
    54 vulnerable dependency paths
    +
    2061 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.23.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.18.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh/knownhosts@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.18.0 + + github.com/go-fed/httpsig@1.1.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.18.0 + + golang.org/x/crypto/ssh/agent@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.23.0 + + golang.org/x/crypto/ssh@0.23.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/rs/cors +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + github.com/rs/cors@1.9.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    +

    PoC

    +
    
    +        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    +            resps := makeFakeResponses(b.N)
    +            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    +            req.Header.Add(headerOrigin, dummyOrigin)
    +            req.Header.Add(headerACRM, http.MethodGet)
    +            req.Header[headerACRH] = adversarialACRH
    +            handler := Default().Handler(testHandler)
    +        
    +            b.ReportAllocs()
    +            b.ResetTimer()
    +            for i := 0; i < b.N; i++ {
    +                handler.ServeHTTP(resps[i], req)
    +            }
    +        }
    +        
    +        var adversarialACRH []string
    +        
    +        func init() { // populates adversarialACRH
    +            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    +            commas := strings.Repeat(",", n)
    +            res := make([]string, n)
    +            for i := range res {
    +                res[i] = commas
    +            }
    +            adversarialACRH = res
    +        }
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    +

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    +

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    +

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    +

    Two common types of DoS vulnerabilities:

    +
      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • +
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      +
    • +
    +

    Remediation

    +

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.18.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.18.0 + + github.com/hashicorp/go-version@1.6.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.13.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/gosimple/slug@1.13.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/Azure/azure-sdk-for-go/sdk/azidentity +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    +

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    +

    Notes:

    +
      +
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      +
    2. +
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      +
    4. +
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      +
    6. +
    7. The vulnerability exists in the following credential types:

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Regular Expression Denial of Service (ReDoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + foundation-sites +
    • + +
    • Introduced through: + + argo-cd-ui@1.0.0 and foundation-sites@6.8.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + foundation-sites@6.8.1 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + foundation-sites@6.8.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    foundation-sites is a responsive front-end framework

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to inefficient backtracking in the regular expressions used in URL forms.

    +

    PoC

    +
    https://www.''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
    +        
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for foundation-sites.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt/v4 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/golang-jwt/jwt/v4@4.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/go-autorest/autorest/azure@0.11.29 + + github.com/Azure/go-autorest/autorest@0.11.29 + + github.com/Azure/go-autorest/autorest/adal@0.9.23 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.6.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential@0.5.2 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens@0.5.2 + + github.com/golang-jwt/jwt@3.2.2 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    A fix was pushed into the master branch but not yet published.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html similarity index 61% rename from docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html index 3c557de6a1064..f8bac868b31c9 100644 --- a/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.12.8/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:21:35 am (UTC+00:00)

    +

    December 15th 2024, 12:26:55 am (UTC+00:00)

    Scanned the following paths: @@ -469,8 +469,8 @@

    Snyk test report

    -
    18 known vulnerabilities
    -
    85 vulnerable dependency paths
    +
    42 known vulnerabilities
    +
    130 vulnerable dependency paths
    829 dependencies

    @@ -479,6 +479,80 @@

    Snyk test report

    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.18.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/crypto/ssh@v0.18.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +

    Allocation of Resources Without Limits or Throttling

    @@ -550,6 +624,7 @@

    References

  • GitHub Commit
  • GitHub Issue
  • Go Advisory
  • +
  • PoC

  • @@ -558,6 +633,74 @@

    References

    More about this vulnerability

    +
    +
    +

    Path Traversal

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/hashicorp/consul/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/consul/api@v1.13.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Path Traversal due to a lack of path normalization, when using URL paths in L7 traffic intentions. An attacker could bypass HTTP request path-based access rules, using URL-encoded paths and/or multiple slashes.

    +

    Remediation

    +

    Upgrade github.com/hashicorp/consul/api to version 1.20.1 or higher.

    +

    References

    + + +
    + + +

    Out-of-bounds Write

    @@ -708,15 +851,15 @@

    Remediation

    References


    @@ -863,25 +1006,1477 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.4-r5 or higher.

    References

    + +
    + + + +
    +
    +

    Infinite loop

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/internal/encoding/json +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/protobuf/internal/encoding/json@v1.31.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/protobuf/internal/encoding/json@v1.32.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function, by unmarshaling certain forms of invalid JSON.

    +

    Note:

    +

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    +

    Remediation

    +

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    +

    References

    +
    + +
    +
    +

    Stack-based Buffer Overflow

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/encoding/protojson +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/protobuf/encoding/protojson@v1.31.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Stack-based Buffer Overflow when processing input that uses pathologically deep nesting.

    +

    Remediation

    +

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.32.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Infinite loop

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/protobuf/encoding/protojson +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/protobuf/encoding/protojson@v1.31.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/protobuf/encoding/protojson@v1.32.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function, by unmarshaling certain forms of invalid JSON.

    +

    Note:

    +

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    +

    Remediation

    +

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/sdk/helper/certutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/logical@v0.5.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/api@v1.6.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/serf/coordinate +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/serf/coordinate@v0.9.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl/v2 +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/json@v2.13.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/token@v1.0.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/golang-lru/simplelru +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/golang-lru/simplelru@v0.5.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-version@v1.5.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-sockaddr +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-sockaddr@v1.0.2 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-sockaddr/template@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/strutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/parseutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/mlock +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-rootcerts +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-rootcerts@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-retryablehttp@v0.7.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    +

    Remediation

    +

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-retryablehttp@v0.7.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-plugin +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-plugin@v1.4.4 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-immutable-radix +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-immutable-radix@v1.3.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/errwrap +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/errwrap@v1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + +
    -

    Infinite loop

    +

    Access Control Bypass

    @@ -900,12 +2495,12 @@

    Infinite loop

  • Vulnerable module: - google.golang.org/protobuf/internal/encoding/json + github.com/hashicorp/consul/api
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/internal/encoding/json@v1.31.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
  • @@ -920,16 +2515,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/internal/encoding/json@v1.31.0 - - - - -
  • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/internal/encoding/json@v1.32.0 + github.com/hashicorp/consul/api@v1.13.0 @@ -941,27 +2527,24 @@

    Detailed paths


    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    +

    Affected versions of this package are vulnerable to Access Control Bypass due to a lack of header normalization while using Headers in L7 traffic intentions. By exploiting this, an attacker could bypass HTTP header based access rules.

    Remediation

    -

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    +

    Upgrade github.com/hashicorp/consul/api to version 1.20.1 or higher.

    References


  • -

    Stack-based Buffer Overflow

    +

    MPL-2.0 license

    @@ -978,14 +2561,14 @@

    Stack-based Buffer Overflow

    Package Manager: golang
  • - Vulnerable module: + Module: - google.golang.org/protobuf/encoding/protojson + github.com/hashicorp/consul/api
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
  • @@ -1000,7 +2583,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/encoding/protojson@v1.31.0 + github.com/hashicorp/consul/api@v1.13.0 @@ -1011,25 +2594,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Stack-based Buffer Overflow when processing input that uses pathologically deep nesting.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.32.0 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Infinite loop

    +

    MPL-2.0 license

    @@ -1046,14 +2621,14 @@

    Infinite loop

    Package Manager: golang
  • - Vulnerable module: + Module: - google.golang.org/protobuf/encoding/protojson + github.com/gosimple/slug
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/protobuf/encoding/protojson@v1.31.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0
  • @@ -1068,16 +2643,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - google.golang.org/protobuf/encoding/protojson@v1.31.0 - - - - -
  • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.32.0 + github.com/gosimple/slug@v1.12.0 @@ -1088,28 +2654,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

    -

    References

    - +

    MPL-2.0 license


  • -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -1120,20 +2675,20 @@

    Insertion of Sensitive Information into Log File

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/hashicorp/go-retryablehttp + github.com/go-sql-driver/mysql
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1
    @@ -1146,9 +2701,9 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + github.com/dexidp/dex@* - github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/go-sql-driver/mysql@v1.7.1 @@ -1159,20 +2714,12 @@

      Detailed paths


      -

      Overview

      -

      Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

      -

      Remediation

      -

      Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

      -

      References

      - +

      MPL-2.0 license


    @@ -1344,6 +2891,7 @@

    Remediation

    References


    @@ -1818,12 +3366,12 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.4-r4 or higher.

    References


    @@ -1969,13 +3517,13 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.4-r6 or higher.

    References


    @@ -2129,13 +3677,13 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.5-r0 or higher.

    References


    @@ -2321,16 +3869,17 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    References


    @@ -2455,9 +4004,43 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.19 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

    +

    Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

    +

    The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

    +

    The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

    +

    The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

    +

    While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    +

    References

    +
    @@ -2611,6 +4194,9 @@

    References

  • https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2
  • https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0
  • https://openssl-library.org/news/secadv/20240903.txt
  • +
  • http://www.openwall.com/lists/oss-security/2024/09/03/4
  • +
  • https://lists.freebsd.org/archives/freebsd-security/2024-September/000303.html
  • +
  • https://security.netapp.com/advisory/ntap-20240912-0001/

  • @@ -2620,6 +4206,169 @@

    References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.19 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 + + busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.19 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.19 openssl to version 3.1.7-r1 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html similarity index 78% rename from docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html rename to docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index c072d3a72b314..e024f2d331cf3 100644 --- a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html +++ b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:21:38 am (UTC+00:00)

    +

    December 15th 2024, 12:26:58 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    5 known vulnerabilities
    -
    42 vulnerable dependency paths
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    18 dependencies
    @@ -871,9 +871,43 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

    +

    Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

    +

    The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

    +

    The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

    +

    The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

    +

    While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    Remediation

    Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

    +

    References

    +
    @@ -1091,16 +1125,17 @@

    Remediation

    Upgrade Alpine:3.20 openssl to version 3.3.1-r1 or higher.

    References


    @@ -1288,6 +1323,9 @@

    References

  • https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2
  • https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0
  • https://openssl-library.org/news/secadv/20240903.txt
  • +
  • http://www.openwall.com/lists/oss-security/2024/09/03/4
  • +
  • https://lists.freebsd.org/archives/freebsd-security/2024-September/000303.html
  • +
  • https://security.netapp.com/advisory/ntap-20240912-0001/

  • @@ -1297,6 +1335,202 @@

    References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html similarity index 51% rename from docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html rename to docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html index da43180e99e7c..46dc068dbad3d 100644 --- a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ b/docs/snyk/v2.12.8/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:21:42 am (UTC+00:00)

    +

    December 15th 2024, 12:27:03 am (UTC+00:00)

    Scanned the following paths: @@ -467,8 +467,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html b/docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html similarity index 55% rename from docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html rename to docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html index 55093f719c826..3366948878d9a 100644 --- a/docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html +++ b/docs/snyk/v2.12.8/quay.io_argoproj_argocd_v2.12.8.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    September 15th 2024, 12:24:11 am (UTC+00:00)

    +

    December 15th 2024, 12:27:23 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.11.8/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.8//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.8/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.8/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.8/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    26 known vulnerabilities
    -
    168 vulnerable dependency paths
    -
    2280 dependencies
    +
    24 known vulnerabilities
    +
    104 vulnerable dependency paths
    +
    2292 dependencies
    @@ -480,19 +480,19 @@

    Snyk test report

    -
    -

    Allocation of Resources Without Limits or Throttling

    +
    +

    Incorrect Implementation of Authentication Algorithm

    -
    - high severity +
    + critical severity

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang @@ -500,12 +500,12 @@

      Allocation of Resources Without Limits or Throttling

      Vulnerable module: - golang.org/x/net/http2 + golang.org/x/crypto/ssh
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.19.0 + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.23.0
    @@ -520,16 +520,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - golang.org/x/net/http2@v0.19.0 - - - - -
  • - Introduced through: - helm.sh/helm/v3@* - - golang.org/x/net/http2@v0.17.0 + golang.org/x/crypto/ssh@v0.23.0 @@ -541,27 +532,30 @@

    Detailed paths


    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    References


  • -

    CVE-2024-41996

    +

    Insecure Storage of Sensitive Information

    @@ -572,20 +566,20 @@

    CVE-2024-41996

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libssl3 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and openssl/libssl3@3.0.2-0ubuntu1.18 + docker-image|quay.io/argoproj/argocd@v2.12.8 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -598,113 +592,174 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + pam/libpam0g@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 + + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + util-linux@2.39.3-9ubuntu6.1 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 + + adduser@3.137ubuntu1 - libfido2/libfido2-1@1.10.0-1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + apt@2.7.14build2 - openssl/libssl3@3.0.2-0ubuntu1.18 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 - ca-certificates@20230311ubuntu0.22.04.1 + adduser@3.137ubuntu1 - openssl@3.0.2-0ubuntu1.18 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 - git@1:2.34.1-1ubuntu1.11 + adduser@3.137ubuntu1 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 + pam/libpam-runtime@1.5.3-5ubuntu5.1 - shadow/passwd@1:4.8.1-2ubuntu2.2 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - pam/libpam-modules@1.4.0-11ubuntu2.4 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - libnsl/libnsl2@1.3.0-2build2 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + apt@2.7.14build2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + adduser@3.137ubuntu1 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3@3.0.2-0ubuntu1.18 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - openssl@3.0.2-0ubuntu1.18 + pam/libpam-runtime@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - ca-certificates@20230311ubuntu0.22.04.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl@3.0.2-0ubuntu1.18 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -716,28 +771,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      A vulnerability was found in PAM. The secret information is stored in memory, where the attacker can trigger the victim program to execute by sending characters to its standard input (stdin). As this occurs, the attacker can train the branch predictor to execute an ROP chain speculatively. This flaw could result in leaked passwords, such as those found in /etc/shadow while performing authentications.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:24.04 pam.

      References


    -

    Information Exposure

    +

    Improper Authentication

    @@ -748,20 +804,20 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - libgcrypt20 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and libgcrypt20@1.9.4-3ubuntu3 + docker-image|quay.io/argoproj/argocd@v2.12.8 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -774,150 +830,174 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpg@2.2.27-3ubuntu2.1 + util-linux@2.39.3-9ubuntu6.1 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 - apt@2.4.13 + adduser@3.137ubuntu1 - apt/libapt-pkg6.0@2.4.13 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 + + adduser@3.137ubuntu1 - apt@2.4.13 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - gnupg2/gpgv@2.2.27-3ubuntu2.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpg@2.2.27-3ubuntu2.1 + apt@2.7.14build2 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 + adduser@3.137ubuntu1 - libgcrypt20@1.9.4-3ubuntu3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + apt@2.7.14build2 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + adduser@3.137ubuntu1 - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + pam/libpam-runtime@1.5.3-5ubuntu5.1 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + apt@2.7.14build2 - gnupg2/gpgsm@2.2.27-3ubuntu2.1 + adduser@3.137ubuntu1 - libgcrypt20@1.9.4-3ubuntu3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - apt@2.4.13 + docker-image|quay.io/argoproj/argocd@v2.12.8 - apt/libapt-pkg6.0@2.4.13 + pam/libpam-runtime@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.8 - systemd/libsystemd0@249.11-0ubuntu3.12 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - libgcrypt20@1.9.4-3ubuntu3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -929,23 +1009,22 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

      +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      A flaw was found in pam_access, where certain rules in its configuration file are mistakenly treated as hostnames. This vulnerability allows attackers to trick the system by pretending to be a trusted hostname, gaining unauthorized access. This issue poses a risk for systems that rely on this feature to control who can access certain services or terminals.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 libgcrypt20.

      +

      There is no fixed version for Ubuntu:24.04 pam.

      References


    @@ -961,10 +1040,10 @@

    CVE-2024-26462

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: @@ -974,8 +1053,8 @@

      CVE-2024-26462

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -987,159 +1066,146 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 + docker-image|quay.io/argoproj/argocd@v2.12.8 - shadow/passwd@1:4.8.1-2ubuntu2.2 + git@1:2.43.0-1ubuntu7.1 - pam/libpam-modules@1.4.0-11ubuntu2.4 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libnsl/libnsl2@1.3.0-2build2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 - libnsl/libnsl2@1.3.0-2build2 + git@1:2.43.0-1ubuntu7.1 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 + docker-image|quay.io/argoproj/argocd@v2.12.8 - shadow/passwd@1:4.8.1-2ubuntu2.2 + git@1:2.43.0-1ubuntu7.1 - pam/libpam-modules@1.4.0-11ubuntu2.4 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libnsl/libnsl2@1.3.0-2build2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + git@1:2.43.0-1ubuntu7.1 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 + docker-image|quay.io/argoproj/argocd@v2.12.8 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - git@1:2.34.1-1ubuntu1.11 + git@1:2.43.0-1ubuntu7.1 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 + docker-image|quay.io/argoproj/argocd@v2.12.8 - shadow/passwd@1:4.8.1-2ubuntu2.2 + git@1:2.43.0-1ubuntu7.1 - pam/libpam-modules@1.4.0-11ubuntu2.4 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libnsl/libnsl2@1.3.0-2build2 + libssh/libssh-4@0.10.6-2build2 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.4 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1152,10 +1218,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/kdc/ndr.c.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 krb5.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References

    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + gopkg.in/retry.v1@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + +
    @@ -1182,7 +1308,7 @@

    Denial of Service (DoS)

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang @@ -1259,7 +1385,7 @@

      Details

      When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

      Two common types of DoS vulnerabilities:

        -
      • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

        +
      • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      • @@ -1281,7 +1407,7 @@

        References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -1292,20 +1418,20 @@

    Insertion of Sensitive Information into Log File

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/hashicorp/go-retryablehttp + github.com/r3labs/diff
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0
    @@ -1320,7 +1446,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - github.com/hashicorp/go-retryablehttp@v0.7.4 + github.com/r3labs/diff@v1.1.0 @@ -1331,25 +1457,17 @@

    Detailed paths


    -

    Overview

    -

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    -

    Remediation

    -

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    -

    References

    - +

    MPL-2.0 license


    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1360,21 +1478,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-version
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.6.0 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1386,11 +1504,9 @@

    Detailed paths

    -

    XML External Entity (XXE) Injection

    +

    MPL-2.0 license

    @@ -1433,21 +1538,21 @@

    XML External Entity (XXE) Injection

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-retryablehttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1459,11 +1564,9 @@

    Detailed paths

    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1506,21 +1598,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/helm/v3 /usr/local/bin/helm
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-multierror
    • Introduced through: + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1532,11 +1624,9 @@

    Detailed paths

    -

    CVE-2024-8096

    +

    MPL-2.0 license

    @@ -1579,21 +1658,21 @@

    CVE-2024-8096

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - curl/libcurl3-gnutls + github.com/hashicorp/go-cleanhttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1605,11 +1684,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 + github.com/argoproj/argo-cd/v2@* - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + github.com/hashicorp/go-cleanhttp@v0.5.2 @@ -1620,53 +1697,41 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      When curl is told to use the Certificate Status Request TLS extension, often referred to as OCSP stapling, to verify that the server certificate is valid, it might fail to detect some OCSP problems and instead wrongly consider the response as fine. If the returned status reports another error than 'revoked' (like for example 'unauthorized') it is not treated as a bad certficate.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 curl.

      -

      References

      - +

      MPL-2.0 license


    -
    -

    CVE-2023-7008

    +
    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - systemd/libsystemd0 + github.com/gosimple/slug
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and systemd/libsystemd0@249.11-0ubuntu3.12 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
    @@ -1679,749 +1744,30 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + github.com/argoproj/argo-cd/v2@* - systemd/libsystemd0@249.11-0ubuntu3.12 + github.com/gosimple/slug@v1.13.1
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - apt@2.4.13 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps/libprocps8@2:3.3.17-6ubuntu2.1 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - util-linux@2.37.2-4ubuntu3.4 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - +
    + +

    MPL-2.0 license

    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - util-linux/bsdutils@1:2.37.2-4ubuntu3.4 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - apt@2.4.13 - - apt/libapt-pkg6.0@2.4.13 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - libfido2/libfido2-1@1.10.0-1 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - util-linux@2.37.2-4ubuntu3.4 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - apt@2.4.13 - - apt/libapt-pkg6.0@2.4.13 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
  • - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream systemd package and not the systemd package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in systemd-resolved. This issue may allow systemd-resolved to accept records of DNSSEC-signed domains even when they have no signature, allowing man-in-the-middles (or the upstream DNS resolver) to manipulate records.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 systemd.

    -

    References

    - - -
    - - - -
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and shadow/passwd@1:4.8.1-2ubuntu2.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - shadow/login@1:4.8.1-2ubuntu2.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 shadow.

    -

    References

    - - -
    - - - -
    -
    -

    Uncontrolled Recursion

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - pcre3/libpcre3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - grep@3.7-1build1 - - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 pcre3.

    -

    References

    - - -
    - - - -
    -
    -

    Release of Invalid Pointer or Reference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    Double Free

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-50495

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - ncurses/libtinfo6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and ncurses/libtinfo6@6.3-2ubuntu0.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - bash@5.1-6ubuntu1.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - less@590-1ubuntu0.22.04.3 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - libedit/libedit2@3.1-20210910-1build1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - util-linux@2.37.2-4ubuntu3.4 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - readline/libreadline8@8.1.2-1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/ncurses-base@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream ncurses package and not the ncurses package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    NCurse v6.4-20230418 was discovered to contain a segmentation fault via the component _nc_wrap_entry().

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 ncurses.

    -

    References

    - - -
    +
    -

    CVE-2023-45918

    +

    Release of Invalid Pointer or Reference

    @@ -2432,20 +1778,20 @@

    CVE-2023-45918

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - ncurses/libtinfo6 + patch
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 and patch@2.7.6-7build3
    @@ -2458,200 +1804,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - bash@5.1-6ubuntu1.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - less@590-1ubuntu0.22.04.3 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - libedit/libedit2@3.1-20210910-1build1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - util-linux@2.37.2-4ubuntu3.4 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - readline/libreadline8@8.1.2-1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - ncurses/ncurses-base@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 + patch@2.7.6-7build3 @@ -2663,27 +1818,26 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream ncurses package and not the ncurses package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      ncurses 6.4-20230610 has a NULL pointer dereference in tgetstr in tinfo/lib_termcap.c.

      +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 ncurses.

      +

      There is no fixed version for Ubuntu:24.04 patch.

      References


    -

    Resource Exhaustion

    +

    Double Free

    @@ -2694,20 +1848,20 @@

    Resource Exhaustion

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - libzstd/libzstd1 + patch
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.12.8 and patch@2.7.6-7build3
    @@ -2720,9 +1874,9 @@

    Detailed paths

    -

    Integer Overflow or Wraparound

    +

    CVE-2024-41996

    @@ -2771,20 +1923,20 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - krb5/libk5crypto3 + openssl/libssl3t64
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 and openssl/libssl3t64@3.0.13-0ubuntu3.4
    @@ -2797,159 +1949,135 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 + coreutils@9.4-3ubuntu6 - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 - libnsl/libnsl2@1.3.0-2build2 + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + libfido2/libfido2-1@1.14.0-1build3 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 + docker-image|quay.io/argoproj/argocd@v2.12.8 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + ca-certificates@20240203 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + openssl@3.0.13-0ubuntu3.4 + + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 - git@1:2.34.1-1ubuntu1.11 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 - git@1:2.34.1-1ubuntu1.11 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + openssl@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + ca-certificates@20240203 - krb5/libkrb5support0@1.19.2-2ubuntu0.4 + openssl@3.0.13-0ubuntu3.4 @@ -2961,30 +2089,28 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      An issue was discovered in MIT Kerberos 5 (aka krb5) through 1.16. There is a variable "dbentry->n_key_data" in kadmin/dbutil/dump.c that can store 16-bit data but unknowingly the developer has assigned a "u4" variable to it, which is for 32-bit data. An attacker can use this vulnerability to affect other artifacts of the database as we know that a Kerberos database dump file contains trusted data.

      +

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 krb5.

      +

      There is no fixed version for Ubuntu:24.04 openssl.

      References


    -

    CVE-2024-26461

    +

    Information Exposure

    @@ -2995,20 +2121,20 @@

    CVE-2024-26461

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - krb5/libk5crypto3 + libgcrypt20
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 and libgcrypt20@1.10.3-2build1
    @@ -3021,159 +2147,100 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + gnupg2/dirmngr@2.4.4-2ubuntu17 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + gnupg2/gpg@2.4.4-2ubuntu17 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 + docker-image|quay.io/argoproj/argocd@v2.12.8 - libnsl/libnsl2@1.3.0-2build2 + gnupg2/gpg-agent@2.4.4-2ubuntu17 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + apt@2.7.14build2 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + apt/libapt-pkg6.0t64@2.7.14build2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - git@1:2.34.1-1ubuntu1.11 + apt@2.7.14build2 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + gnupg2/gpgv@2.4.4-2ubuntu17 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - git@1:2.34.1-1ubuntu1.11 + gnupg2/gpg@2.4.4-2ubuntu17 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + gnupg2/gpgconf@2.4.4-2ubuntu17 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 + docker-image|quay.io/argoproj/argocd@v2.12.8 - shadow/passwd@1:4.8.1-2ubuntu2.2 + apt@2.7.14build2 - pam/libpam-modules@1.4.0-11ubuntu2.4 + adduser@3.137ubuntu1 - libnsl/libnsl2@1.3.0-2build2 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + systemd/libsystemd0@255.4-1ubuntu8.4 - krb5/libkrb5support0@1.19.2-2ubuntu0.4 + libgcrypt20@1.10.3-2build1 @@ -3185,22 +2252,24 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/lib/gssapi/krb5/k5sealv3.c.

      +

      Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 krb5.

      +

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      References


    @@ -3216,10 +2285,10 @@

    CVE-2024-26458

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: @@ -3229,8 +2298,8 @@

      CVE-2024-26458

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -3242,159 +2311,146 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 + docker-image|quay.io/argoproj/argocd@v2.12.8 - pam/libpam-modules@1.4.0-11ubuntu2.4 + git@1:2.43.0-1ubuntu7.1 - libnsl/libnsl2@1.3.0-2build2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 + git@1:2.43.0-1ubuntu7.1 - shadow/passwd@1:4.8.1-2ubuntu2.2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - pam/libpam-modules@1.4.0-11ubuntu2.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.4 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - adduser@3.118ubuntu5 + git@1:2.43.0-1ubuntu7.1 - shadow/passwd@1:4.8.1-2ubuntu2.2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - pam/libpam-modules@1.4.0-11ubuntu2.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - libnsl/libnsl2@1.3.0-2build2 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - git@1:2.34.1-1ubuntu1.11 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 + docker-image|quay.io/argoproj/argocd@v2.12.8 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + git@1:2.43.0-1ubuntu7.1 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 + docker-image|quay.io/argoproj/argocd@v2.12.8 - pam/libpam-modules@1.4.0-11ubuntu2.4 + git@1:2.43.0-1ubuntu7.1 - libnsl/libnsl2@1.3.0-2build2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.4 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -3407,10 +2463,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak in /krb5/src/lib/rpc/pmap_rmt.c.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 krb5.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References

    -

    Out-of-bounds Write

    +

    CVE-2024-26461

    @@ -3437,21 +2493,21 @@

    Out-of-bounds Write

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - gnupg2/gpgv + krb5/libk5crypto3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -3463,313 +2519,288 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + git@1:2.43.0-1ubuntu7.1 - apt@2.4.13 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - gnupg2/gpgv@2.2.27-3ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - gnupg2/gpg@2.2.27-3ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpgsm@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - gnupg2/gpg@2.2.27-3ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - gnupg2/gpg@2.2.27-3ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/gpg@2.2.27-3ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - gnupg2/gpg@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + libssh/libssh-4@0.10.6-2build2 - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - +
    - +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/lib/gssapi/krb5/k5sealv3.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + gnupg2/gpgv +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.8 and gnupg2/gpgv@2.4.4-2ubuntu17 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + gnupg2/gpgv@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + gnupg2/dirmngr@2.4.4-2ubuntu17 - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + gnupg2/gpg@2.4.4-2ubuntu17 - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gpgsm@2.2.27-3ubuntu2.1 + gnupg2/dirmngr@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpgsm@2.2.27-3ubuntu2.1 + gnupg2/gpg@2.4.4-2ubuntu17
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - gnupg2/gnupg@2.2.27-3ubuntu2.1 + gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -3782,10 +2813,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream gnupg2 package and not the gnupg2 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      GnuPG can be made to spin on a relatively small input by (for example) crafting a public key with thousands of signatures attached, compressed down to just a few KB.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 gnupg2.

      +

      There is no fixed version for Ubuntu:24.04 gnupg2.

      References

    @@ -3816,10 +2847,10 @@

    Allocation of Resources Without Limits or Throttling

  • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
  • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
  • Vulnerable module: @@ -3829,7 +2860,7 @@

    Allocation of Resources Without Limits or Throttling

    Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and glibc/libc-bin@2.35-0ubuntu3.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 and glibc/libc-bin@2.39-0ubuntu8.3
  • @@ -3842,18 +2873,18 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - glibc/libc-bin@2.35-0ubuntu3.8 + glibc/libc-bin@2.39-0ubuntu8.3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - glibc/libc6@2.35-0ubuntu3.8 + glibc/libc6@2.39-0ubuntu8.3 @@ -3866,10 +2897,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      sha256crypt and sha512crypt through 0.6 allow attackers to cause a denial of service (CPU consumption) because the algorithm's runtime is proportional to the square of the length of the password.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 glibc.

      +

      There is no fixed version for Ubuntu:24.04 glibc.

      References

    -

    Improper Input Validation

    +

    Insufficient Documentation of Error Handling Techniques

    @@ -3897,21 +2928,21 @@

    Improper Input Validation

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • Vulnerable module: - git/git-man + github.com/golang-jwt/jwt/v4
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt/v4@v4.5.0 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -3923,31 +2954,78 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 + github.com/argoproj/argo-cd/v2@* - git/git-man@1:2.34.1-1ubuntu1.11 + github.com/golang-jwt/jwt/v4@v4.5.0
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 - - +
    - +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt@v3.2.2+incompatible + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git-lfs@3.0.2-1ubuntu0.2 + github.com/argoproj/argo-cd/v2@* - git@1:2.34.1-1ubuntu1.11 + github.com/golang-jwt/jwt@v3.2.2+incompatible @@ -3958,28 +3036,26 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream git package and not the git package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      GIT version 2.15.1 and earlier contains a Input Validation Error vulnerability in Client that can result in problems including messing up terminal configuration to RCE. This attack appear to be exploitable via The user must interact with a malicious git server, (or have their traffic modified in a MITM attack).

      +

      Overview

      +

      Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

      +

      Workaround

      +

      Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 git.

      +

      A fix was pushed into the master branch but not yet published.

      References


    -

    Uncontrolled Recursion

    +

    Improper Input Validation

    @@ -3990,21 +3066,21 @@

    Uncontrolled Recursion

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: - gcc-12/libstdc++6 + git/git-man
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + docker-image|quay.io/argoproj/argocd@v2.12.8, git@1:2.43.0-1ubuntu7.1 and others
    @@ -4016,51 +3092,31 @@

    Detailed paths

    @@ -4105,10 +3159,10 @@

    Improper Input Validation

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.8/argoproj/argocd Dockerfile
    • - Package Manager: ubuntu:22.04 + Package Manager: ubuntu:24.04
    • Vulnerable module: @@ -4118,7 +3172,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and coreutils@8.32-4.1ubuntu1.2 + docker-image|quay.io/argoproj/argocd@v2.12.8 and coreutils@9.4-3ubuntu6
    @@ -4131,9 +3185,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.12.8 - coreutils@8.32-4.1ubuntu1.2 + coreutils@9.4-3ubuntu6 @@ -4146,10 +3200,10 @@

      Detailed paths

      NVD Description

      Note: Versions mentioned in the description apply only to the upstream coreutils package and not the coreutils package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 coreutils.

      +

      There is no fixed version for Ubuntu:24.04 coreutils.

      References

    diff --git a/docs/snyk/v2.11.8/redis_7.0.15-alpine.html b/docs/snyk/v2.12.8/redis_7.0.15-alpine.html similarity index 52% rename from docs/snyk/v2.11.8/redis_7.0.15-alpine.html rename to docs/snyk/v2.12.8/redis_7.0.15-alpine.html index 3f02438fedc1d..c7a1a3757c771 100644 --- a/docs/snyk/v2.11.8/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.12.8/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:24:16 am (UTC+00:00)

    +

    December 15th 2024, 12:27:27 am (UTC+00:00)

    Scanned the following paths: @@ -467,8 +467,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.11.8/argocd-iac-install.html b/docs/snyk/v2.13.2/argocd-iac-install.html similarity index 98% rename from docs/snyk/v2.11.8/argocd-iac-install.html rename to docs/snyk/v2.13.2/argocd-iac-install.html index d1f9777c282dd..ab0d42998efdd 100644 --- a/docs/snyk/v2.11.8/argocd-iac-install.html +++ b/docs/snyk/v2.13.2/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:25:35 am (UTC+00:00)

    +

    December 15th 2024, 12:26:19 am (UTC+00:00)

    Scanned the following path: @@ -507,7 +507,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 21059 + Line number: 22402
  • @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20744 + Line number: 22083
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20829 + Line number: 22170
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20857 + Line number: 22198
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20887 + Line number: 22228
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20905 + Line number: 22246
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20923 + Line number: 22264
  • @@ -829,7 +829,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20945 + Line number: 22286
  • @@ -881,7 +881,7 @@

    Container could be running with outdated image

  • - Line number: 21991 + Line number: 23358
  • @@ -933,7 +933,7 @@

    Container could be running with outdated image

  • - Line number: 22278 + Line number: 23657
  • @@ -991,7 +991,7 @@

    Container has no CPU limit

  • - Line number: 21552 + Line number: 22895
  • @@ -1049,7 +1049,7 @@

    Container has no CPU limit

  • - Line number: 21803 + Line number: 23164
  • @@ -1107,7 +1107,7 @@

    Container has no CPU limit

  • - Line number: 21769 + Line number: 23118
  • @@ -1165,7 +1165,7 @@

    Container has no CPU limit

  • - Line number: 21863 + Line number: 23224
  • @@ -1223,7 +1223,7 @@

    Container has no CPU limit

  • - Line number: 21962 + Line number: 23329
  • @@ -1281,7 +1281,7 @@

    Container has no CPU limit

  • - Line number: 21986 + Line number: 23353
  • @@ -1339,7 +1339,7 @@

    Container has no CPU limit

  • - Line number: 22278 + Line number: 23657
  • @@ -1397,7 +1397,7 @@

    Container has no CPU limit

  • - Line number: 22043 + Line number: 23410
  • @@ -1455,7 +1455,7 @@

    Container has no CPU limit

  • - Line number: 22363 + Line number: 23742
  • @@ -1513,7 +1513,7 @@

    Container has no CPU limit

  • - Line number: 22714 + Line number: 24132
  • @@ -1565,7 +1565,7 @@

    Container is running with multiple open ports

  • - Line number: 21783 + Line number: 23144
  • @@ -1617,7 +1617,7 @@

    Container is running without liveness probe

  • - Line number: 21552 + Line number: 22895
  • @@ -1669,7 +1669,7 @@

    Container is running without liveness probe

  • - Line number: 21769 + Line number: 23118
  • @@ -1721,7 +1721,7 @@

    Container is running without liveness probe

  • - Line number: 21962 + Line number: 23329
  • @@ -1779,7 +1779,7 @@

    Container is running without memory limit

  • - Line number: 21552 + Line number: 22895
  • @@ -1837,7 +1837,7 @@

    Container is running without memory limit

  • - Line number: 21769 + Line number: 23118
  • @@ -1895,7 +1895,7 @@

    Container is running without memory limit

  • - Line number: 21803 + Line number: 23164
  • @@ -1953,7 +1953,7 @@

    Container is running without memory limit

  • - Line number: 21863 + Line number: 23224
  • @@ -2011,7 +2011,7 @@

    Container is running without memory limit

  • - Line number: 21962 + Line number: 23329
  • @@ -2069,7 +2069,7 @@

    Container is running without memory limit

  • - Line number: 21986 + Line number: 23353
  • @@ -2127,7 +2127,7 @@

    Container is running without memory limit

  • - Line number: 22278 + Line number: 23657
  • @@ -2185,7 +2185,7 @@

    Container is running without memory limit

  • - Line number: 22043 + Line number: 23410
  • @@ -2243,7 +2243,7 @@

    Container is running without memory limit

  • - Line number: 22363 + Line number: 23742
  • @@ -2301,7 +2301,7 @@

    Container is running without memory limit

  • - Line number: 22714 + Line number: 24132
  • @@ -2357,7 +2357,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21693 + Line number: 23042
  • @@ -2413,7 +2413,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21811 + Line number: 23172
  • @@ -2469,7 +2469,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21786 + Line number: 23147
  • @@ -2525,7 +2525,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21896 + Line number: 23263
  • @@ -2581,7 +2581,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21979 + Line number: 23346
  • @@ -2637,7 +2637,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21993 + Line number: 23360
  • @@ -2693,7 +2693,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22285 + Line number: 23664
  • @@ -2749,7 +2749,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22251 + Line number: 23630
  • @@ -2805,7 +2805,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22624 + Line number: 24033
  • @@ -2861,7 +2861,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22915 + Line number: 24351
  • diff --git a/docs/snyk/v2.10.16/argocd-iac-namespace-install.html b/docs/snyk/v2.13.2/argocd-iac-namespace-install.html similarity index 98% rename from docs/snyk/v2.10.16/argocd-iac-namespace-install.html rename to docs/snyk/v2.13.2/argocd-iac-namespace-install.html index c2f25c827ce3a..e9e1a24ff1288 100644 --- a/docs/snyk/v2.10.16/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.13.2/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 15th 2024, 12:27:58 am (UTC+00:00)

    +

    December 15th 2024, 12:26:29 am (UTC+00:00)

    Scanned the following path: @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 162 + Line number: 164
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 190 + Line number: 192
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 220 + Line number: 222
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 238 + Line number: 240
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 256 + Line number: 258
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 278 + Line number: 280
  • @@ -835,7 +835,7 @@

    Container could be running with outdated image

  • - Line number: 1112 + Line number: 1138
  • @@ -887,7 +887,7 @@

    Container could be running with outdated image

  • - Line number: 1393 + Line number: 1437
  • @@ -945,7 +945,7 @@

    Container has no CPU limit

  • - Line number: 673 + Line number: 675
  • @@ -1003,7 +1003,7 @@

    Container has no CPU limit

  • - Line number: 924 + Line number: 944
  • @@ -1061,7 +1061,7 @@

    Container has no CPU limit

  • - Line number: 890 + Line number: 898
  • @@ -1119,7 +1119,7 @@

    Container has no CPU limit

  • - Line number: 984 + Line number: 1004
  • @@ -1177,7 +1177,7 @@

    Container has no CPU limit

  • - Line number: 1083 + Line number: 1109
  • @@ -1235,7 +1235,7 @@

    Container has no CPU limit

  • - Line number: 1107 + Line number: 1133
  • @@ -1293,7 +1293,7 @@

    Container has no CPU limit

  • - Line number: 1393 + Line number: 1437
  • @@ -1351,7 +1351,7 @@

    Container has no CPU limit

  • - Line number: 1164 + Line number: 1190
  • @@ -1409,7 +1409,7 @@

    Container has no CPU limit

  • - Line number: 1478 + Line number: 1522
  • @@ -1467,7 +1467,7 @@

    Container has no CPU limit

  • - Line number: 1829 + Line number: 1912
  • @@ -1519,7 +1519,7 @@

    Container is running with multiple open ports

  • - Line number: 904 + Line number: 924
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 673 + Line number: 675
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 890 + Line number: 898
  • @@ -1675,7 +1675,7 @@

    Container is running without liveness probe

  • - Line number: 1083 + Line number: 1109
  • @@ -1733,7 +1733,7 @@

    Container is running without memory limit

  • - Line number: 673 + Line number: 675
  • @@ -1791,7 +1791,7 @@

    Container is running without memory limit

  • - Line number: 890 + Line number: 898
  • @@ -1849,7 +1849,7 @@

    Container is running without memory limit

  • - Line number: 924 + Line number: 944
  • @@ -1907,7 +1907,7 @@

    Container is running without memory limit

  • - Line number: 984 + Line number: 1004
  • @@ -1965,7 +1965,7 @@

    Container is running without memory limit

  • - Line number: 1083 + Line number: 1109
  • @@ -2023,7 +2023,7 @@

    Container is running without memory limit

  • - Line number: 1107 + Line number: 1133
  • @@ -2081,7 +2081,7 @@

    Container is running without memory limit

  • - Line number: 1393 + Line number: 1437
  • @@ -2139,7 +2139,7 @@

    Container is running without memory limit

  • - Line number: 1164 + Line number: 1190
  • @@ -2197,7 +2197,7 @@

    Container is running without memory limit

  • - Line number: 1478 + Line number: 1522
  • @@ -2255,7 +2255,7 @@

    Container is running without memory limit

  • - Line number: 1829 + Line number: 1912
  • @@ -2311,7 +2311,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 814 + Line number: 822
  • @@ -2367,7 +2367,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 932 + Line number: 952
  • @@ -2423,7 +2423,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 907 + Line number: 927
  • @@ -2479,7 +2479,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1017 + Line number: 1043
  • @@ -2535,7 +2535,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1100 + Line number: 1126
  • @@ -2591,7 +2591,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1114 + Line number: 1140
  • @@ -2647,7 +2647,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1400 + Line number: 1444
  • @@ -2703,7 +2703,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1366 + Line number: 1410
  • @@ -2759,7 +2759,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1739 + Line number: 1813
  • @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 2030 + Line number: 2131
  • diff --git a/docs/snyk/v2.13.2/argocd-test.html b/docs/snyk/v2.13.2/argocd-test.html new file mode 100644 index 0000000000000..c25d755fd46d7 --- /dev/null +++ b/docs/snyk/v2.13.2/argocd-test.html @@ -0,0 +1,1910 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:24:18 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/ui/yarn.lock (yarn)
    • +
    +
    + +
    +
    11 known vulnerabilities
    +
    53 vulnerable dependency paths
    +
    2131 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and golang.org/x/crypto/ssh@0.27.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.19.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + golang.org/x/crypto/ssh/knownhosts@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.19.0 + + github.com/go-fed/httpsig@1.1.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.19.0 + + golang.org/x/crypto/ssh/agent@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/xanzy/ssh-agent@0.3.3 + + golang.org/x/crypto/ssh/agent@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/go-git/go-git/v5@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/client@5.12.0 + + github.com/go-git/go-git/v5/plumbing/transport/ssh@5.12.0 + + github.com/skeema/knownhosts@1.2.2 + + golang.org/x/crypto/ssh/knownhosts@0.27.0 + + golang.org/x/crypto/ssh@0.27.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.19.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.19.0 + + github.com/hashicorp/go-version@1.6.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.109.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.109.0 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.109.0 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/gosimple/slug@1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/Azure/azure-sdk-for-go/sdk/azidentity +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    +

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    +

    Notes:

    +
      +
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      +
    2. +
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      +
    4. +
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      +
    6. +
    7. The vulnerability exists in the following credential types:

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Regular Expression Denial of Service (ReDoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + foundation-sites +
    • + +
    • Introduced through: + + argo-cd-ui@1.0.0 and foundation-sites@6.8.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + foundation-sites@6.8.1 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + foundation-sites@6.8.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    foundation-sites is a responsive front-end framework

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to inefficient backtracking in the regular expressions used in URL forms.

    +

    PoC

    +
    https://www.''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
    +        
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for foundation-sites.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt/v4 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/golang-jwt/jwt/v4@4.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/go-autorest/autorest/azure@0.11.29 + + github.com/Azure/go-autorest/autorest@0.11.29 + + github.com/Azure/go-autorest/autorest/adal@0.9.23 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 + + github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + + github.com/bradleyfalzon/ghinstallation/v2@2.11.0 + + github.com/golang-jwt/jwt/v4@4.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential@0.5.2 + + github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens@0.5.2 + + github.com/golang-jwt/jwt@3.2.2 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    A fix was pushed into the master branch but not yet published.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html b/docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html new file mode 100644 index 0000000000000..0c92c0b6203f9 --- /dev/null +++ b/docs/snyk/v2.13.2/ghcr.io_dexidp_dex_v2.41.1.html @@ -0,0 +1,2170 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:24:25 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • ghcr.io/dexidp/dex:v2.41.1/dexidp/dex (apk)
    • +
    • ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4//usr/local/bin/gomplate (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.41.1/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • +
    • ghcr.io/dexidp/dex:v2.41.1/dexidp/dex//usr/local/bin/dex (gomodules)
    • +
    +
    + +
    +
    23 known vulnerabilities
    +
    44 vulnerable dependency paths
    +
    969 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and golang.org/x/crypto/ssh@v0.24.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + golang.org/x/crypto/ssh@v0.24.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc/metadata +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + google.golang.org/grpc/metadata@v1.64.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc/metadata is a package that defines the structure of the metadata supported by the gRPC library

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File in the form of gRPC metadata. If the metadata contains sensitive information an attacker can expose it.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc/metadata to version 1.64.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/vault/api@v1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/vault/api@v1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/serf/coordinate +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/serf/coordinate@v0.10.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/serf/coordinate@v0.10.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex /usr/local/bin/dex +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl/v2 +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/json@v2.13.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/hcl@v1.0.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/hcl@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/hcl/hcl/token@v1.0.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/golang-lru/simplelru +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/golang-lru/simplelru@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/golang-lru/simplelru@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-uuid +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-uuid@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-uuid@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-sockaddr +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-sockaddr@v1.0.6 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-sockaddr@v1.0.6 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-sockaddr/template@v1.0.6 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/strutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/parseutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.8 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/awsutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-secure-stdlib/awsutil@v0.3.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-rootcerts +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-rootcerts@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-rootcerts@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-retryablehttp@v0.7.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-multierror +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-multierror@v1.1.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-multierror@v1.1.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-immutable-radix +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-immutable-radix@v1.3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-immutable-radix@v1.3.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/errwrap +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/errwrap@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/errwrap@v1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/consul/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/hashicorp/consul/api@v1.29.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/hashicorp/consul/api@v1.29.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v4@* and github.com/gosimple/slug@v1.14.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v4@* + + github.com/gosimple/slug@v1.14.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.41.1/dexidp/dex /usr/local/bin/dex +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/go-sql-driver/mysql +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.8.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/go-sql-driver/mysql@v1.8.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + openssl/libcrypto3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.41.1 + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.1-r3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html new file mode 100644 index 0000000000000..b539d1cc9fc95 --- /dev/null +++ b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -0,0 +1,1539 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:24:28 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy (apk)
    • +
    +
    + +
    +
    6 known vulnerabilities
    +
    52 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|public.ecr.aws/docker/library/haproxy
    Path public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy
    Package Manager apk
    +
    +
    +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_free_buffers may cause + memory to be accessed that was previously freed in some situations

    +

    Impact summary: A use after free can have a range of potential consequences such + as the corruption of valid data, crashes or execution of arbitrary code. + However, only applications that directly call the SSL_free_buffers function are + affected by this issue. Applications that do not call this function are not + vulnerable. Our investigations indicate that this function is rarely used by + applications.

    +

    The SSL_free_buffers function is used to free the internal OpenSSL buffer used + when processing an incoming record from the network. The call is only expected + to succeed if the buffer is not currently in use. However, two scenarios have + been identified where the buffer is freed even when still in use.

    +

    The first scenario occurs where a record header has been received from the + network and processed by OpenSSL, but the full record body has not yet arrived. + In this case calling SSL_free_buffers will succeed even though a record has only + been partially processed and the buffer is still in use.

    +

    The second scenario occurs where a full record containing application data has + been received and processed by OpenSSL but the application has only read part of + this data. Again a call to SSL_free_buffers will succeed even though the buffer + is still in use.

    +

    While these scenarios could occur accidentally during normal operation a + malicious attacker could attempt to engineer a stituation where this occurs. + We are not aware of this issue being actively exploited.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-5535

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an + empty supported client protocols buffer may cause a crash or memory contents to + be sent to the peer.

    +

    Impact summary: A buffer overread can have a range of potential consequences + such as unexpected application beahviour or a crash. In particular this issue + could result in up to 255 bytes of arbitrary private data from memory being sent + to the peer leading to a loss of confidentiality. However, only applications + that directly call the SSL_select_next_proto function with a 0 length list of + supported client protocols are affected by this issue. This would normally never + be a valid scenario and is typically not under attacker control but may occur by + accident in the case of a configuration or programming error in the calling + application.

    +

    The OpenSSL API function SSL_select_next_proto is typically used by TLS + applications that support ALPN (Application Layer Protocol Negotiation) or NPN + (Next Protocol Negotiation). NPN is older, was never standardised and + is deprecated in favour of ALPN. We believe that ALPN is significantly more + widely deployed than NPN. The SSL_select_next_proto function accepts a list of + protocols from the server and a list of protocols from the client and returns + the first protocol that appears in the server list that also appears in the + client list. In the case of no overlap between the two lists it returns the + first item in the client list. In either case it will signal whether an overlap + between the two lists was found. In the case where SSL_select_next_proto is + called with a zero length client list it fails to notice this condition and + returns the memory immediately following the client list pointer (and reports + that there was no overlap in the lists).

    +

    This function is typically called from a server side application callback for + ALPN or a client side application callback for NPN. In the case of ALPN the list + of protocols supplied by the client is guaranteed by libssl to never be zero in + length. The list of server protocols comes from the application and should never + normally be expected to be of zero length. In this case if the + SSL_select_next_proto function has been called as expected (with the list + supplied by the client passed in the client/client_len parameters), then the + application will not be vulnerable to this issue. If the application has + accidentally been configured with a zero length server list, and has + accidentally passed that zero length server list in the client/client_len + parameters, and has additionally failed to correctly handle a "no overlap" + response (which would normally result in a handshake failure in ALPN) then it + will be vulnerable to this problem.

    +

    In the case of NPN, the protocol permits the client to opportunistically select + a protocol when there is no overlap. OpenSSL returns the first client protocol + in the no overlap case in support of this. The list of client protocols comes + from the application and should never normally be expected to be of zero length. + However if the SSL_select_next_proto function is accidentally called with a + client_len of 0 then an invalid memory pointer will be returned instead. If the + application uses this output as the opportunistic protocol then the loss of + confidentiality will occur.

    +

    This issue has been assessed as Low severity because applications are most + likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not + widely used. It also requires an application configuration or programming error. + Finally, this issue would not typically be under attacker control making active + exploitation unlikely.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Due to the low severity of this issue we are not issuing new releases of + OpenSSL at this time. The fix will be included in the next releases when they + become available.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.1-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..9ad65012ffb57 --- /dev/null +++ b/docs/snyk/v2.13.2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,670 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    December 15th 2024, 12:24:32 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • public.ecr.aws/docker/library/redis:7.0.15-alpine/docker/library/redis (apk)
    • +
    • public.ecr.aws/docker/library/redis:7.0.15-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
    • +
    +
    + +
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html b/docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html similarity index 73% rename from docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html rename to docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html index ec4329b79d670..a5b69352548de 100644 --- a/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html +++ b/docs/snyk/v2.13.2/quay.io_argoproj_argocd_v2.13.2.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    September 15th 2024, 12:21:58 am (UTC+00:00)

    +

    December 15th 2024, 12:24:50 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.12.3/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.12.3/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.3//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.3/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.12.3/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.2/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.2//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.2/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.2/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    17 known vulnerabilities
    -
    81 vulnerable dependency paths
    -
    2292 dependencies
    +
    23 known vulnerabilities
    +
    103 vulnerable dependency paths
    +
    2354 dependencies

    @@ -480,8 +480,82 @@

    Snyk test report

    +
    +

    Incorrect Implementation of Authentication Algorithm

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/crypto/ssh +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/crypto/ssh@v0.27.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + golang.org/x/crypto/ssh@v0.27.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/crypto/ssh is a SSH client and server

    +

    Affected versions of this package are vulnerable to Incorrect Implementation of Authentication Algorithm when the key passed in the last call before a connection is established is assumed to be the key used for authentication. It is not necessarily the authentication key in use, and this allows attackers who can control the key cache by making their own carefully-timed connections to bypass authorization with subsequent legitimate ServerConfig.PublicKeyCallback callbacks.

    +

    Note: The assumed caching behavior of this callback is not documented and is therefore considered human error, but the project maintainers have observed reliance on it for authorization decisions in production. In fact, the assumption is negated in the documentation, which states "A call to this function does not guarantee that the key offered is in fact used to authenticate." The behavior after upgrading still allows the possibility of an attacker forcing their own key to be the one in the cache when the callback is invoked if the client is using a different authentication method such as PasswordCallback, KeyboardInteractiveCallback, or NoClientAuth. It is therefore recommended to rely on the return values of the connection itself, found in ServerConn.Permissions for further authorization steps.

    +

    Remediation

    +

    Upgrade golang.org/x/crypto/ssh to version 0.31.0 or higher.

    +

    References

    + + +
    + + + +
    -

    CVE-2024-41996

    +

    Insecure Storage of Sensitive Information

    @@ -492,7 +566,7 @@

    CVE-2024-41996

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -500,12 +574,12 @@

      CVE-2024-41996

    • Vulnerable module: - openssl/libssl3t64 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and openssl/libssl3t64@3.0.13-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -518,135 +592,174 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - coreutils@9.4-3ubuntu6 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + util-linux@2.39.3-9ubuntu6.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - libfido2/libfido2-1@1.14.0-1build3 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + apt@2.7.14build2 + + adduser@3.137ubuntu1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - ca-certificates@20240203 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + apt@2.7.14build2 - libssh/libssh-4@0.10.6-2build2 + adduser@3.137ubuntu1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + pam/libpam-modules-bin@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 + docker-image|quay.io/argoproj/argocd@v2.13.2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + apt@2.7.14build2 - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + adduser@3.137ubuntu1 - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - ca-certificates@20240203 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -658,28 +771,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      +

      A vulnerability was found in PAM. The secret information is stored in memory, where the attacker can trigger the victim program to execute by sending characters to its standard input (stdin). As this occurs, the attacker can train the branch predictor to execute an ROP chain speculatively. This flaw could result in leaked passwords, such as those found in /etc/shadow while performing authentications.

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 openssl.

      +

      There is no fixed version for Ubuntu:24.04 pam.

      References


    -

    CVE-2024-6119

    +

    Improper Authentication

    @@ -690,7 +804,7 @@

    CVE-2024-6119

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -698,12 +812,12 @@

      CVE-2024-6119

    • Vulnerable module: - openssl/libssl3t64 + pam/libpam0g
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and openssl/libssl3t64@3.0.13-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and pam/libpam0g@1.5.3-5ubuntu5.1
    @@ -716,135 +830,174 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - coreutils@9.4-3ubuntu6 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + util-linux@2.39.3-9ubuntu6.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - libfido2/libfido2-1@1.14.0-1build3 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - ca-certificates@20240203 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 + + pam/libpam-modules@1.5.3-5ubuntu5.1 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam0g@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + apt@2.7.14build2 + + adduser@3.137ubuntu1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - libssh/libssh-4@0.10.6-2build2 + pam/libpam-modules@1.5.3-5ubuntu5.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam-modules-bin@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - git@1:2.43.0-1ubuntu7.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 + docker-image|quay.io/argoproj/argocd@v2.13.2 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + apt@2.7.14build2 - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + adduser@3.137ubuntu1 - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + shadow/passwd@1:4.13+dfsg1-4ubuntu3.2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + pam/libpam-modules@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - ca-certificates@20240203 + shadow/login@1:4.13+dfsg1-4ubuntu3.2 - openssl@3.0.13-0ubuntu3.3 + pam/libpam-runtime@1.5.3-5ubuntu5.1 @@ -856,48 +1009,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream pam package and not the pam package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      Issue summary: Applications performing certificate name checks (e.g., TLS - clients checking server certificates) may attempt to read an invalid memory - address resulting in abnormal termination of the application process.

      -

      Impact summary: Abnormal termination of an application can a cause a denial of - service.

      -

      Applications performing certificate name checks (e.g., TLS clients checking - server certificates) may attempt to read an invalid memory address when - comparing the expected name with an otherName subject alternative name of an - X.509 certificate. This may result in an exception that terminates the - application program.

      -

      Note that basic certificate chain validation (signatures, dates, ...) is not - affected, the denial of service can occur only when the application also - specifies an expected DNS name, Email address or IP address.

      -

      TLS servers rarely solicit client certificates, and even when they do, they - generally don't perform a name check against a reference identifier (expected - identity), but rather extract the presented identity after checking the - certificate chain. So TLS servers are generally not affected and the severity - of the issue is Moderate.

      -

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      +

      A flaw was found in pam_access, where certain rules in its configuration file are mistakenly treated as hostnames. This vulnerability allows attackers to trick the system by pretending to be a trusted hostname, gaining unauthorized access. This issue poses a risk for systems that rely on this feature to control who can access certain services or terminals.

      Remediation

      -

      Upgrade Ubuntu:24.04 openssl to version 3.0.13-0ubuntu3.4 or higher.

      +

      There is no fixed version for Ubuntu:24.04 pam.

      References


    -

    Information Exposure

    +

    CVE-2024-26462

    @@ -908,7 +1040,7 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -916,13 +1048,13 @@

      Information Exposure

    • Vulnerable module: - libgcrypt20 + krb5/libk5crypto3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and libgcrypt20@1.10.3-2build1 + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -934,100 +1066,146 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - libgcrypt20@1.10.3-2build1 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - gnupg2/dirmngr@2.4.4-2ubuntu17 + git@1:2.43.0-1ubuntu7.1 - libgcrypt20@1.10.3-2build1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - gnupg2/gpg@2.4.4-2ubuntu17 + git@1:2.43.0-1ubuntu7.1 - libgcrypt20@1.10.3-2build1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - gnupg2/gpg-agent@2.4.4-2ubuntu17 + git@1:2.43.0-1ubuntu7.1 - libgcrypt20@1.10.3-2build1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - apt@2.7.14build2 + git@1:2.43.0-1ubuntu7.1 - apt/libapt-pkg6.0t64@2.7.14build2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libgcrypt20@1.10.3-2build1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + krb5/libk5crypto3@1.20.1-6ubuntu2.2 + + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - apt@2.7.14build2 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpgv@2.4.4-2ubuntu17 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - libgcrypt20@1.10.3-2build1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - gnupg2/gpg@2.4.4-2ubuntu17 + docker-image|quay.io/argoproj/argocd@v2.13.2 - gnupg2/gpgconf@2.4.4-2ubuntu17 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - libgcrypt20@1.10.3-2build1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - apt@2.7.14build2 + git@1:2.43.0-1ubuntu7.1 - adduser@3.137ubuntu1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 - shadow/passwd@1:4.13+dfsg1-4ubuntu3 + git@1:2.43.0-1ubuntu7.1 - pam/libpam-modules@1.5.3-5ubuntu5.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - systemd/libsystemd0@255.4-1ubuntu8.4 + libssh/libssh-4@0.10.6-2build2 - libgcrypt20@1.10.3-2build1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -1039,28 +1217,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      -

      A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

      +

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/kdc/ndr.c.

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References


    -

    CVE-2024-26462

    +

    LGPL-3.0 license

    @@ -1071,21 +1248,21 @@

    CVE-2024-26462

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - krb5/libk5crypto3 + gopkg.in/retry.v1
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1097,146 +1274,189 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + github.com/argoproj/argo-cd/v2@* - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + gopkg.in/retry.v1@v1.0.3
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - krb5/libk5crypto3@1.20.1-6ubuntu2.1 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5support0@1.20.1-6ubuntu2.1 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - krb5/libkrb5support0@1.20.1-6ubuntu2.1 - - +
    + +

    LGPL-3.0 license

    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - krb5/libk5crypto3@1.20.1-6ubuntu2.1 - - krb5/libkrb5support0@1.20.1-6ubuntu2.1 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - openssh/openssh-client@1:9.6p1-3ubuntu13.5 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - +
  • +
    +

    MPL-2.0 license

    +
    - +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + github.com/argoproj/argo-cd/v2@* - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + github.com/r3labs/diff@v1.1.0
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.6.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 - - libssh/libssh-4@0.10.6-2build2 + github.com/argoproj/argo-cd/v2@* - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + github.com/hashicorp/go-version@v1.6.0
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    Denial of Service (DoS)

    +

    MPL-2.0 license

    @@ -1279,20 +1488,20 @@

    Denial of Service (DoS)

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.13.2/helm/v3 /usr/local/bin/helm
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/rs/cors + github.com/hashicorp/go-multierror
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0 + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1
    @@ -1305,9 +1514,9 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@* + helm.sh/helm/v3@* - github.com/rs/cors@v1.9.0 + github.com/hashicorp/go-multierror@v1.1.1 @@ -1318,67 +1527,17 @@

      Detailed paths


      -

      Overview

      -

      Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

      -

      PoC

      -
      
      -        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
      -            resps := makeFakeResponses(b.N)
      -            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
      -            req.Header.Add(headerOrigin, dummyOrigin)
      -            req.Header.Add(headerACRM, http.MethodGet)
      -            req.Header[headerACRH] = adversarialACRH
      -            handler := Default().Handler(testHandler)
      -        
      -            b.ReportAllocs()
      -            b.ResetTimer()
      -            for i := 0; i < b.N; i++ {
      -                handler.ServeHTTP(resps[i], req)
      -            }
      -        }
      -        
      -        var adversarialACRH []string
      -        
      -        func init() { // populates adversarialACRH
      -            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
      -            commas := strings.Repeat(",", n)
      -            res := make([]string, n)
      -            for i := range res {
      -                res[i] = commas
      -            }
      -            adversarialACRH = res
      -        }
      -        
      -

      Details

      -

      Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

      -

      Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

      -

      One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

      -

      When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

      -

      Two common types of DoS vulnerabilities:

      -
        -
      • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

        -
      • -
      • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

        -
      • -
      -

      Remediation

      -

      Upgrade github.com/rs/cors to version 1.11.0 or higher.

      -

      References

      - +

      MPL-2.0 license


    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1389,21 +1548,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/hashicorp/go-cleanhttp
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1415,11 +1574,9 @@

    Detailed paths

    -

    XML External Entity (XXE) Injection

    +

    MPL-2.0 license

    @@ -1462,21 +1608,21 @@

    XML External Entity (XXE) Injection

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - expat/libexpat1 + github.com/gosimple/slug
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.14.0 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1488,11 +1634,9 @@

    Detailed paths

    -
    -

    Integer Overflow or Wraparound

    +
    +

    Release of Invalid Pointer or Reference

    -
    - medium severity +
    + low severity

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1543,13 +1676,13 @@

      Integer Overflow or Wraparound

    • Vulnerable module: - expat/libexpat1 + patch
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 and patch@2.7.6-7build3 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1561,11 +1694,9 @@

    Detailed paths

    -
    -

    CVE-2024-8096

    +
    +

    Double Free

    -
    - medium severity +
    + low severity

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1616,13 +1746,13 @@

      CVE-2024-8096

    • Vulnerable module: - curl/libcurl3t64-gnutls + patch
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 and patch@2.7.6-7build3 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1634,11 +1764,9 @@

    Detailed paths

    -

    Release of Invalid Pointer or Reference

    +

    CVE-2024-41996

    @@ -1682,7 +1813,7 @@

    Release of Invalid Pointer or Reference

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1690,12 +1821,12 @@

      Release of Invalid Pointer or Reference

    • Vulnerable module: - patch + openssl/libssl3t64
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and openssl/libssl3t64@3.0.13-0ubuntu3.4
    @@ -1703,14 +1834,140 @@

    Release of Invalid Pointer or Reference


    -

    Detailed paths

    +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.4 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 + + krb5/libkrb5-3@1.20.1-6ubuntu2.2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8.1 + + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.2 + + openssl@3.0.13-0ubuntu3.4 + + -
    -

    Double Free

    +

    Information Exposure

    @@ -1752,7 +2011,7 @@

    Double Free

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1760,12 +2019,12 @@

      Double Free

    • Vulnerable module: - patch + libgcrypt20
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and libgcrypt20@1.10.3-2build1
    @@ -1778,9 +2037,100 @@

    Detailed paths

    @@ -1827,7 +2175,7 @@

    CVE-2024-26458

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1841,7 +2189,7 @@

      CVE-2024-26458

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1853,146 +2201,146 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - krb5/krb5-locales@1.20.1-6ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -2035,7 +2383,7 @@

      CVE-2024-26461

      • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:24.04 @@ -2049,7 +2397,7 @@

        CVE-2024-26461

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others
      @@ -2061,146 +2409,146 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2 - krb5/libk5crypto3@1.20.1-6ubuntu2.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.2 - krb5/libkrb5support0@1.20.1-6ubuntu2.1 + krb5/libkrb5support0@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.5 libssh/libssh-4@0.10.6-2build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.2
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - krb5/krb5-locales@1.20.1-6ubuntu2.1 + krb5/krb5-locales@1.20.1-6ubuntu2.2 @@ -2243,7 +2591,7 @@

        Out-of-bounds Write

        • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2256,7 +2604,7 @@

          Out-of-bounds Write

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and gnupg2/gpgv@2.4.4-2ubuntu17 + docker-image|quay.io/argoproj/argocd@v2.13.2 and gnupg2/gpgv@2.4.4-2ubuntu17
        @@ -2269,7 +2617,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/gpgv@2.4.4-2ubuntu17 @@ -2278,7 +2626,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 apt@2.7.14build2 @@ -2289,7 +2637,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -2300,7 +2648,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -2311,7 +2659,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/gpg@2.4.4-2ubuntu17 @@ -2322,7 +2670,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -2331,7 +2679,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/gpg@2.4.4-2ubuntu17 @@ -2340,7 +2688,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -2389,7 +2737,7 @@

          Allocation of Resources Without Limits or Throttling

        • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2402,7 +2750,7 @@

          Allocation of Resources Without Limits or Throttling

          Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and glibc/libc-bin@2.39-0ubuntu8.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 and glibc/libc-bin@2.39-0ubuntu8.3
        @@ -2415,7 +2763,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 glibc/libc-bin@2.39-0ubuntu8.3 @@ -2424,7 +2772,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 glibc/libc6@2.39-0ubuntu8.3 @@ -2457,6 +2805,144 @@

          References

          More about this vulnerability

    +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt/v4 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt/v4@v4.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/golang-jwt/jwt/v4@v4.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    Upgrade github.com/golang-jwt/jwt/v4 to version 4.5.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Insufficient Documentation of Error Handling Techniques

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/golang-jwt/jwt +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/golang-jwt/jwt@v3.2.2+incompatible + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/golang-jwt/jwt@v3.2.2+incompatible + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Insufficient Documentation of Error Handling Techniques in the ParseWithClaims function. An attacker can exploit this to accept invalid tokens by only checking for specific errors and ignoring others.

    +

    Workaround

    +

    Users who are not able to upgrade to the fixed version should make sure that they are properly checking for all errors, see example_test.go

    +

    Remediation

    +

    A fix was pushed into the master branch but not yet published.

    +

    References

    + + +
    + + +

    Improper Input Validation

    @@ -2470,7 +2956,7 @@

    Improper Input Validation

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -2484,7 +2970,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others + docker-image|quay.io/argoproj/argocd@v2.13.2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -2496,7 +2982,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 @@ -2507,7 +2993,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 git@1:2.43.0-1ubuntu7.1 @@ -2516,9 +3002,9 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 - git-lfs@3.4.1-1ubuntu0.1 + git-lfs@3.4.1-1ubuntu0.2 git@1:2.43.0-1ubuntu7.1 @@ -2563,7 +3049,7 @@

      Improper Input Validation

      • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.13.2/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:24.04 @@ -2576,7 +3062,7 @@

        Improper Input Validation

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and coreutils@9.4-3ubuntu6 + docker-image|quay.io/argoproj/argocd@v2.13.2 and coreutils@9.4-3ubuntu6
      @@ -2589,7 +3075,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.13.2 coreutils@9.4-3ubuntu6 diff --git a/docs/snyk/v2.12.3/redis_7.0.15-alpine.html b/docs/snyk/v2.13.2/redis_7.0.15-alpine.html similarity index 52% rename from docs/snyk/v2.12.3/redis_7.0.15-alpine.html rename to docs/snyk/v2.13.2/redis_7.0.15-alpine.html index 222dff64476b7..1d00ef99b889f 100644 --- a/docs/snyk/v2.12.3/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.13.2/redis_7.0.15-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

        Snyk test report

        -

        September 15th 2024, 12:22:01 am (UTC+00:00)

        +

        December 15th 2024, 12:24:54 am (UTC+00:00)

        Scanned the following paths: @@ -467,8 +467,8 @@

        Snyk test report

        -
        0 known vulnerabilities
        -
        0 vulnerable dependency paths
        +
        1 known vulnerabilities
        +
        9 vulnerable dependency paths
        18 dependencies
    @@ -476,7 +476,193 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + openssl/libcrypto3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + .redis-rundeps@20240906.232324 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.15-alpine + + busybox/ssl_client@1.36.1-r29 + + openssl/libssl3@3.3.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Use of the low-level GF(2^m) elliptic curve APIs with untrusted + explicit values for the field polynomial can lead to out-of-bounds memory reads + or writes.

    +

    Impact summary: Out of bound memory writes can lead to an application crash or + even a possibility of a remote code execution, however, in all the protocols + involving Elliptic Curve Cryptography that we're aware of, either only "named + curves" are supported, or, if explicit curve parameters are supported, they + specify an X9.62 encoding of binary (GF(2^m)) curves that can't represent + problematic input values. Thus the likelihood of existence of a vulnerable + application is low.

    +

    In particular, the X9.62 encoding is used for ECC keys in X.509 certificates, + so problematic inputs cannot occur in the context of processing X.509 + certificates. Any problematic use-cases would have to be using an "exotic" + curve encoding.

    +

    The affected APIs include: EC_GROUP_new_curve_GF2m(), EC_GROUP_new_from_params(), + and various supporting BN_GF2m_*() functions.

    +

    Applications working with "exotic" explicit binary (GF(2^m)) curve parameters, + that make it possible to represent invalid field polynomials with a zero + constant term, via the above or similar APIs, may terminate abruptly as a + result of reading or writing outside of array bounds. Remote code execution + cannot easily be ruled out.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/try_argo_cd_locally.md b/docs/try_argo_cd_locally.md new file mode 100644 index 0000000000000..2d08105875551 --- /dev/null +++ b/docs/try_argo_cd_locally.md @@ -0,0 +1,53 @@ +# Try Argo CD Locally + +!!! tip + This guide assumes you have a grounding in the tools that Argo CD is based on. Please read [understanding the basics](understand_the_basics.md) to learn about these tools. + + +Follow these steps to install `Kind` for local development and set it up with Argo CD. + +To run an Argo CD development environment [review the developer guide for running locally](../developer-guide/running-locally). + +## Install Kind + +Install Kind Following Instructions [here](https://kind.sigs.k8s.io/docs/user/quick-start#installation). + +## Create a Kind Cluster +Once Kind is installed, create a new Kubernetes cluster with: +```bash +kind create cluster --name argocd-cluster +``` +This will create a local Kubernetes cluster named `argocd-cluster`. + +## Set Up kubectl to Use the Kind Cluster +After creating the cluster, set `kubectl` to use your new `kind` cluster: +```bash +kubectl cluster-info --context kind-argocd-cluster +``` +This command verifies that `kubectl` is pointed to the right cluster. + +## Install ArgoCD on the Cluster +You can now install Argo CD on your `kind` cluster. First, apply the Argo CD manifest to create the necessary resources: +```bash +kubectl create namespace argocd +kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml +``` + +## Expose ArgoCD API Server +By default, Argo CD's API server is not exposed outside the cluster. You need to expose it to access the UI locally. For development purposes, you can use Kubectl 'port-forward'. +```bash +kubectl port-forward svc/argocd-server -n argocd 8080:443 +``` +This will forward port 8080 on your local machine to the ArgoCD API server’s port 443 inside the Kubernetes cluster. + +## Access ArgoCD UI +Now, you can open your browser and navigate to http://localhost:8080 to access the ArgoCD UI. + +### Log in to ArgoCD +To log in to the ArgoCD UI, you'll need the default admin password. You can retrieve it from the Kubernetes cluster: +```bash +kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d +``` +Use the admin username and the retrieved password to log in. + +You can now move on to step #2 in the [Getting Started Guide](getting_started.md]. diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 2b4e9968dcfb4..df5fd278893bb 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -21,7 +21,7 @@ ## Labels -| Label key | Target resource(es) | Possible values | Description | -|--------------------------------|---------------------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| argocd.argoproj.io/instance | Application | any | Recommended tracking label to [avoid conflicts with other tools which use `app.kubernetes.io/instance`](../faq.md#why-is-my-app-out-of-sync-even-after-syncing). | -| argocd.argoproj.io/secret-type | Secret | `cluster`, `repository`, `repo-creds` | Identifies certain types of Secrets used by Argo CD. See the [Declarative Setup docs](../operator-manual/declarative-setup.md) for details. | +| Label key | Target resource(es) | Possible values | Description | +|--------------------------------|---------------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| argocd.argoproj.io/instance | Application | any | Recommended tracking label to [avoid conflicts with other tools which use `app.kubernetes.io/instance`](../faq.md#why-is-my-app-out-of-sync-even-after-syncing). | +| argocd.argoproj.io/secret-type | Secret | `cluster`, `repository`, `repo-creds`, `scm-creds` | Identifies certain types of Secrets used by Argo CD. See the [Declarative Setup docs](../operator-manual/declarative-setup.md) for details about the first three, and [AppSet-in-any-namespace docs](../operator-manual/applicationset/Appset-Any-Namespace.md) for the last one. | diff --git a/docs/user-guide/auto_sync.md b/docs/user-guide/auto_sync.md index 7dd9c3b5ac2e9..66e20c9fc0bea 100644 --- a/docs/user-guide/auto_sync.md +++ b/docs/user-guide/auto_sync.md @@ -75,6 +75,8 @@ spec: selfHeal: true ``` +Disabling self-heal does not guarantee that live cluster changes won't be reverted in multi-source applications. Even if a resource's source remains unchanged, changes in one of the sources can trigger `autosync`. To handle such cases, consider disabling `autosync`. + ## Automated Sync Semantics * An automated sync will only be performed if the application is OutOfSync. Applications in a diff --git a/docs/user-guide/commands/argocd.md b/docs/user-guide/commands/argocd.md index 0514eb9447103..a72d5c0264bd6 100644 --- a/docs/user-guide/commands/argocd.md +++ b/docs/user-guide/commands/argocd.md @@ -30,6 +30,7 @@ argocd [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") @@ -47,6 +48,7 @@ argocd [flags] * [argocd cert](argocd_cert.md) - Manage repository certificates and SSH known hosts entries * [argocd cluster](argocd_cluster.md) - Manage cluster credentials * [argocd completion](argocd_completion.md) - output shell completion code for the specified shell (bash, zsh or fish) +* [argocd configure](argocd_configure.md) - Manage local configuration * [argocd context](argocd_context.md) - Switch between contexts * [argocd gpg](argocd_gpg.md) - Manage GPG keys used for signature verification * [argocd login](argocd_login.md) - Log in to Argo CD diff --git a/docs/user-guide/commands/argocd_account.md b/docs/user-guide/commands/argocd_account.md index 25eaa7d214542..ec28edfb9976e 100644 --- a/docs/user-guide/commands/argocd_account.md +++ b/docs/user-guide/commands/argocd_account.md @@ -70,6 +70,7 @@ argocd account [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_bcrypt.md b/docs/user-guide/commands/argocd_account_bcrypt.md index d4bde8b933424..b45f3084615a6 100644 --- a/docs/user-guide/commands/argocd_account_bcrypt.md +++ b/docs/user-guide/commands/argocd_account_bcrypt.md @@ -43,6 +43,7 @@ argocd account bcrypt --password YOUR_PASSWORD --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_can-i.md b/docs/user-guide/commands/argocd_account_can-i.md index f6fd5a01880a8..150f90353e2d0 100644 --- a/docs/user-guide/commands/argocd_account_can-i.md +++ b/docs/user-guide/commands/argocd_account_can-i.md @@ -21,8 +21,8 @@ argocd account can-i update projects 'default' # Can I create a cluster? argocd account can-i create clusters '*' -Actions: [get create update delete sync override] -Resources: [clusters projects applications applicationsets repositories certificates logs exec] +Actions: [get create update delete sync override action invoke] +Resources: [clusters projects applications applicationsets repositories write-repositories certificates accounts gpgkeys logs exec extensions] ``` @@ -53,6 +53,7 @@ Resources: [clusters projects applications applicationsets repositories certific --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_delete-token.md b/docs/user-guide/commands/argocd_account_delete-token.md index 25d5b9a37d17a..a9f6b0e833eba 100644 --- a/docs/user-guide/commands/argocd_account_delete-token.md +++ b/docs/user-guide/commands/argocd_account_delete-token.md @@ -46,6 +46,7 @@ argocd account delete-token --account ID --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_generate-token.md b/docs/user-guide/commands/argocd_account_generate-token.md index e149548374894..be15939b2842f 100644 --- a/docs/user-guide/commands/argocd_account_generate-token.md +++ b/docs/user-guide/commands/argocd_account_generate-token.md @@ -48,6 +48,7 @@ argocd account generate-token --account --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_get-user-info.md b/docs/user-guide/commands/argocd_account_get-user-info.md index 577f103b48c0d..ddda242551221 100644 --- a/docs/user-guide/commands/argocd_account_get-user-info.md +++ b/docs/user-guide/commands/argocd_account_get-user-info.md @@ -46,6 +46,7 @@ argocd account get-user-info [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_get.md b/docs/user-guide/commands/argocd_account_get.md index 70d181e702a17..543a60339c72e 100644 --- a/docs/user-guide/commands/argocd_account_get.md +++ b/docs/user-guide/commands/argocd_account_get.md @@ -47,6 +47,7 @@ argocd account get --account --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_list.md b/docs/user-guide/commands/argocd_account_list.md index 6af9d8a6d0ee0..4df2ef874c6df 100644 --- a/docs/user-guide/commands/argocd_account_list.md +++ b/docs/user-guide/commands/argocd_account_list.md @@ -42,6 +42,7 @@ argocd account list --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_account_update-password.md b/docs/user-guide/commands/argocd_account_update-password.md index 3a31b6ee06274..10055a6cdde0f 100644 --- a/docs/user-guide/commands/argocd_account_update-password.md +++ b/docs/user-guide/commands/argocd_account_update-password.md @@ -58,6 +58,7 @@ argocd account update-password [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md index ec1de309c135b..01e5c0f8e909d 100644 --- a/docs/user-guide/commands/argocd_admin.md +++ b/docs/user-guide/commands/argocd_admin.md @@ -46,6 +46,7 @@ $ argocd admin initial-password reset --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_app.md b/docs/user-guide/commands/argocd_admin_app.md index 12fa400c8c94d..24976c02d816c 100644 --- a/docs/user-guide/commands/argocd_admin_app.md +++ b/docs/user-guide/commands/argocd_admin_app.md @@ -50,6 +50,7 @@ argocd admin app get-reconcile-results APPNAME --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_app_diff-reconcile-results.md b/docs/user-guide/commands/argocd_admin_app_diff-reconcile-results.md index c77a3d3db57e0..4173abf69aba1 100644 --- a/docs/user-guide/commands/argocd_admin_app_diff-reconcile-results.md +++ b/docs/user-guide/commands/argocd_admin_app_diff-reconcile-results.md @@ -35,6 +35,7 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_app_generate-spec.md b/docs/user-guide/commands/argocd_admin_app_generate-spec.md index 2826917d4765c..c5e4ee3ac433b 100644 --- a/docs/user-guide/commands/argocd_admin_app_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_app_generate-spec.md @@ -45,6 +45,9 @@ argocd admin app generate-spec APPNAME [flags] --directory-exclude string Set glob expression used to exclude files from application source path --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory + --dry-source-path string Path in repository to the app directory for the dry source + --dry-source-repo string Repository URL of the app dry source + --dry-source-revision string Revision of the app dry source --env string Application environment to monitor -f, --file string Filename or URL to Kubernetes manifests for the app --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster @@ -56,8 +59,11 @@ argocd admin app generate-spec APPNAME [flags] --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) --helm-set-string stringArray Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2) --helm-skip-crds Skip helm crd installation step + --helm-skip-schema-validation Skip helm schema validation step + --helm-skip-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for generate-spec + --hydrate-to-branch string The branch to hydrate the app to --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values -i, --inline If set then generated resource is written back to the file specified in --file flag --jsonnet-ext-var-code stringArray Jsonnet ext var @@ -92,12 +98,15 @@ argocd admin app generate-spec APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion + --source-name string Name of the source from the list of sources of the app. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) --sync-retry-backoff-factor int Factor multiplies the base duration after each failed sync retry (default 2) --sync-retry-backoff-max-duration duration Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s) --sync-retry-limit int Max number of allowed sync retries + --sync-source-branch string The branch from which the app will sync + --sync-source-path string The path in the repository from which the app will sync --validate Validation of repo and cluster (default true) --values stringArray Helm values file(s) to use --values-literal-file string Filename or URL to import as a literal Helm values block @@ -124,6 +133,7 @@ argocd admin app generate-spec APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md index a985a7d0e8484..506dc49e31b2c 100644 --- a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md +++ b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md @@ -61,6 +61,7 @@ argocd admin app get-reconcile-results PATH [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index 7abe6fd1a42f8..960f8e5e54c2d 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -49,6 +49,7 @@ argocd admin cluster namespaces my-cluster --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md index 01a0fe6ff3a07..2921858837553 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md @@ -18,6 +18,7 @@ argocd admin cluster generate-spec CONTEXT [flags] --bearer-token string Authentication token that should be used to access K8S API server --cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'. --cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty. + --disable-compression Bypasses automatic GZip compression requests to the server --exec-command string Command to run to provide client credentials to the cluster. You may need to build a custom ArgoCD image to ensure the command is available at runtime. --exec-command-api-version string Preferred input version of the ExecInfo for the --exec-command executable --exec-command-args stringArray Arguments to supply to the --exec-command executable @@ -58,6 +59,7 @@ argocd admin cluster generate-spec CONTEXT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 37092a4ef303a..f89da6c89db4d 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -72,6 +72,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md index 791f61ec1c1f0..634f2291ca87f 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md @@ -55,6 +55,7 @@ argocd admin cluster namespaces [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md index 57b776ff1cc3d..21231b19f8e96 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md @@ -56,6 +56,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md index cfbfd2fb891ab..c10e0ad44d997 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md @@ -58,6 +58,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index b624c8dbe6c49..5d0c528fccca7 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -71,6 +71,7 @@ argocd admin cluster shards [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index b894959c1c0c3..298b75605537a 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -85,6 +85,7 @@ argocd admin cluster stats target-cluster --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index ecfee6be3a242..12795450309d9 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -72,6 +72,7 @@ $ argocd admin dashboard --redis-compress gzip --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md index f4fe070f2d1f5..9b2f8cf24db40 100644 --- a/docs/user-guide/commands/argocd_admin_export.md +++ b/docs/user-guide/commands/argocd_admin_export.md @@ -58,6 +58,7 @@ argocd admin export [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md index b373184a3796d..1dd65a79e9fbe 100644 --- a/docs/user-guide/commands/argocd_admin_import.md +++ b/docs/user-guide/commands/argocd_admin_import.md @@ -29,6 +29,7 @@ argocd admin import SOURCE [flags] --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request --password string Password for basic authentication to the API server + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --prune Prune secrets, applications and projects which do not appear in the backup --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md index 92feb9e8ad9f5..c363b4206d2c5 100644 --- a/docs/user-guide/commands/argocd_admin_initial-password.md +++ b/docs/user-guide/commands/argocd_admin_initial-password.md @@ -55,6 +55,7 @@ argocd admin initial-password [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md index 58f2b832bebbb..a35c9345189ae 100644 --- a/docs/user-guide/commands/argocd_admin_notifications.md +++ b/docs/user-guide/commands/argocd_admin_notifications.md @@ -60,6 +60,7 @@ argocd admin notifications [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_notifications_template.md b/docs/user-guide/commands/argocd_admin_notifications_template.md index 2a93df1a9a9f1..b0488aab2a29a 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template.md @@ -52,6 +52,7 @@ argocd admin notifications template [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_get.md b/docs/user-guide/commands/argocd_admin_notifications_template_get.md index e48bb8271d4db..5fb698f8bc3d2 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md @@ -64,6 +64,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md index cfcb6bc08db89..f55e0c3367302 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md @@ -65,6 +65,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger.md b/docs/user-guide/commands/argocd_admin_notifications_trigger.md index 74b8460151e2e..f3000d00daf3f 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger.md @@ -52,6 +52,7 @@ argocd admin notifications trigger [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md index 6d3f7aa9b3200..df00c18c23111 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md @@ -64,6 +64,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md index 6b27a7a54d27f..f21224062786d 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md @@ -64,6 +64,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_proj.md b/docs/user-guide/commands/argocd_admin_proj.md index e4f11de54cab1..5ea290e4f1dc3 100644 --- a/docs/user-guide/commands/argocd_admin_proj.md +++ b/docs/user-guide/commands/argocd_admin_proj.md @@ -35,6 +35,7 @@ argocd admin proj [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md index 753d0fa68a704..767507ed46be7 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md @@ -63,6 +63,7 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_proj_generate-spec.md b/docs/user-guide/commands/argocd_admin_proj_generate-spec.md index c94eba4365ef8..c25d24f6bef73 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-spec.md @@ -12,13 +12,13 @@ argocd admin proj generate-spec PROJECT [flags] ``` # Generate a YAML configuration for a project named "myproject" - argocd admin projects generate-spec myproject + argocd admin proj generate-spec myproject # Generate a JSON configuration for a project named "anotherproject" and specify an output file - argocd admin projects generate-spec anotherproject --output json --file config.json + argocd admin proj generate-spec anotherproject --output json --file config.json # Generate a YAML configuration for a project named "someproject" and write it back to the input file - argocd admin projects generate-spec someproject --inline + argocd admin proj generate-spec someproject --inline ``` ### Options @@ -30,6 +30,7 @@ argocd admin proj generate-spec PROJECT [flags] --deny-namespaced-resource stringArray List of denied namespaced resources --description string Project description -d, --dest stringArray Permitted destination server and namespace (e.g. https://192.168.99.100:8443,default) + --dest-service-accounts stringArray Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa) -f, --file string Filename or URL to Kubernetes manifests for the project -h, --help help for generate-spec -i, --inline If set then generated resource is written back to the file specified in --file flag @@ -62,6 +63,7 @@ argocd admin proj generate-spec PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md index 09dc8994d2a7f..9e086f0281aca 100644 --- a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md +++ b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md @@ -12,10 +12,10 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] ``` # Add policy that allows executing any action (action/*) to roles which name matches to *deployer* in all projects - argocd admin projects update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow + argocd admin proj update-role-policy '*' set 'action/*' --role '*deployer*' --resource applications --scope '*' --permission allow # Remove policy that which manages running (action/*) from all roles which name matches *deployer* in all projects - argocd admin projects update-role-policy '*' remove override --role '*deployer*' + argocd admin proj update-role-policy '*' remove override --role '*deployer*' ``` @@ -71,6 +71,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_redis-initial-password.md b/docs/user-guide/commands/argocd_admin_redis-initial-password.md index de2653e962f5e..379eee92de705 100644 --- a/docs/user-guide/commands/argocd_admin_redis-initial-password.md +++ b/docs/user-guide/commands/argocd_admin_redis-initial-password.md @@ -55,6 +55,7 @@ argocd admin redis-initial-password [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_repo.md b/docs/user-guide/commands/argocd_admin_repo.md index 33944fda2d87c..2593d718087cb 100644 --- a/docs/user-guide/commands/argocd_admin_repo.md +++ b/docs/user-guide/commands/argocd_admin_repo.md @@ -35,6 +35,7 @@ argocd admin repo [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_repo_generate-spec.md b/docs/user-guide/commands/argocd_admin_repo_generate-spec.md index 3616e057c53c7..5f1895d6055a8 100644 --- a/docs/user-guide/commands/argocd_admin_repo_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_repo_generate-spec.md @@ -83,6 +83,7 @@ argocd admin repo generate-spec REPOURL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md index d2726048afc42..bfe95f0a4fa42 100644 --- a/docs/user-guide/commands/argocd_admin_settings.md +++ b/docs/user-guide/commands/argocd_admin_settings.md @@ -58,6 +58,7 @@ argocd admin settings [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac.md b/docs/user-guide/commands/argocd_admin_settings_rbac.md index 5cb18ba1a0580..cc3696f9a8242 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac.md @@ -51,6 +51,7 @@ argocd admin settings rbac [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md index 5697d68530c4d..9d8a8254533a2 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md @@ -93,6 +93,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md index 6e5721e705fb1..b6d36703f555d 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -85,6 +85,7 @@ argocd admin settings rbac validate --namespace argocd --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md index 095ae66f6fb39..839d82b0cfd33 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md @@ -51,6 +51,7 @@ argocd admin settings resource-overrides [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md index 8d1afb6e81b42..ae0a883cf01a0 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md @@ -62,6 +62,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md index c10989511069e..1b9df109a1961 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md @@ -62,6 +62,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md index f562e3557ccfd..3a846632d21f8 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md @@ -63,6 +63,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml - --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md index 144a7d0b9d92b..70d46dd90bac2 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md @@ -62,6 +62,7 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md index 99f5c903d11c2..494a61c4fd51e 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md @@ -16,7 +16,7 @@ argocd admin settings resource-overrides run-action RESOURCE_YAML_PATH ACTION [f ``` -argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --argocd-cm-path ./argocd-cm.yaml +argocd admin settings resource-overrides action /tmp/deploy.yaml restart --argocd-cm-path ./argocd-cm.yaml ``` ### Options @@ -62,6 +62,7 @@ argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --a --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_admin_settings_validate.md b/docs/user-guide/commands/argocd_admin_settings_validate.md index 1565397fb5117..7a7612575c07c 100644 --- a/docs/user-guide/commands/argocd_admin_settings_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_validate.md @@ -67,6 +67,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index ea5bf74d6a56a..2ff8e6cf830ff 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -67,6 +67,7 @@ argocd app [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") @@ -80,6 +81,7 @@ argocd app [flags] * [argocd](argocd.md) - argocd controls a Argo CD server * [argocd app actions](argocd_app_actions.md) - Manage Resource actions * [argocd app add-source](argocd_app_add-source.md) - Adds a source to the list of sources in the application +* [argocd app confirm-deletion](argocd_app_confirm-deletion.md) - Confirms deletion/pruning of an application resources * [argocd app create](argocd_app_create.md) - Create an application * [argocd app delete](argocd_app_delete.md) - Delete an application * [argocd app delete-resource](argocd_app_delete-resource.md) - Delete resource in an application @@ -92,7 +94,7 @@ argocd app [flags] * [argocd app manifests](argocd_app_manifests.md) - Print manifests of an application * [argocd app patch](argocd_app_patch.md) - Patch application * [argocd app patch-resource](argocd_app_patch-resource.md) - Patch resource in an application -* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. Counting starts with 1. Default value is -1. +* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. * [argocd app resources](argocd_app_resources.md) - List resource of application * [argocd app rollback](argocd_app_rollback.md) - Rollback application to a previous deployed version by History ID, omitted will Rollback to the previous version * [argocd app set](argocd_app_set.md) - Set application parameters diff --git a/docs/user-guide/commands/argocd_app_actions.md b/docs/user-guide/commands/argocd_app_actions.md index 21df6d1f1564e..ad1d96daeb710 100644 --- a/docs/user-guide/commands/argocd_app_actions.md +++ b/docs/user-guide/commands/argocd_app_actions.md @@ -45,6 +45,7 @@ argocd app actions [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_actions_list.md b/docs/user-guide/commands/argocd_app_actions_list.md index 513042b746278..77bedda0c665f 100644 --- a/docs/user-guide/commands/argocd_app_actions_list.md +++ b/docs/user-guide/commands/argocd_app_actions_list.md @@ -47,6 +47,7 @@ argocd app actions list APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_actions_run.md b/docs/user-guide/commands/argocd_app_actions_run.md index 8dc105243793b..d3da3b40fc1c2 100644 --- a/docs/user-guide/commands/argocd_app_actions_run.md +++ b/docs/user-guide/commands/argocd_app_actions_run.md @@ -47,6 +47,7 @@ argocd app actions run APPNAME ACTION [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_add-source.md b/docs/user-guide/commands/argocd_app_add-source.md index b6bc3ae3de6c2..72f2f98cf0616 100644 --- a/docs/user-guide/commands/argocd_app_add-source.md +++ b/docs/user-guide/commands/argocd_app_add-source.md @@ -12,7 +12,7 @@ argocd app add-source APPNAME [flags] ``` # Append a source to the list of sources in the application - argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook + argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --source-name guestbook ``` ### Options @@ -28,6 +28,9 @@ argocd app add-source APPNAME [flags] --directory-exclude string Set glob expression used to exclude files from application source path --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory + --dry-source-path string Path in repository to the app directory for the dry source + --dry-source-repo string Repository URL of the app dry source + --dry-source-revision string Revision of the app dry source --env string Application environment to monitor --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name @@ -38,8 +41,11 @@ argocd app add-source APPNAME [flags] --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) --helm-set-string stringArray Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2) --helm-skip-crds Skip helm crd installation step + --helm-skip-schema-validation Skip helm schema validation step + --helm-skip-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for add-source + --hydrate-to-branch string The branch to hydrate the app to --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -69,12 +75,15 @@ argocd app add-source APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated + --source-name string Name of the source from the list of sources of the app. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) --sync-retry-backoff-factor int Factor multiplies the base duration after each failed sync retry (default 2) --sync-retry-backoff-max-duration duration Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s) --sync-retry-limit int Max number of allowed sync retries + --sync-source-branch string The branch from which the app will sync + --sync-source-path string The path in the repository from which the app will sync --validate Validation of repo and cluster (default true) --values stringArray Helm values file(s) to use --values-literal-file string Filename or URL to import as a literal Helm values block @@ -101,6 +110,7 @@ argocd app add-source APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_confirm-deletion.md b/docs/user-guide/commands/argocd_app_confirm-deletion.md new file mode 100644 index 0000000000000..f9a77904f128f --- /dev/null +++ b/docs/user-guide/commands/argocd_app_confirm-deletion.md @@ -0,0 +1,51 @@ +# `argocd app confirm-deletion` Command Reference + +## argocd app confirm-deletion + +Confirms deletion/pruning of an application resources + +``` +argocd app confirm-deletion APPNAME [flags] +``` + +### Options + +``` + -N, --app-namespace string Namespace of the target application where the source will be appended + -h, --help help for confirm-deletion +``` + +### Options inherited from parent commands + +``` + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server string Argo CD server address + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd app](argocd_app.md) - Manage applications + diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 662ee0b92644a..0dc043f83febb 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -47,6 +47,9 @@ argocd app create APPNAME [flags] --directory-exclude string Set glob expression used to exclude files from application source path --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory + --dry-source-path string Path in repository to the app directory for the dry source + --dry-source-repo string Repository URL of the app dry source + --dry-source-revision string Revision of the app dry source --env string Application environment to monitor -f, --file string Filename or URL to Kubernetes manifests for the app --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster @@ -58,8 +61,11 @@ argocd app create APPNAME [flags] --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) --helm-set-string stringArray Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2) --helm-skip-crds Skip helm crd installation step + --helm-skip-schema-validation Skip helm schema validation step + --helm-skip-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for create + --hydrate-to-branch string The branch to hydrate the app to --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -92,12 +98,15 @@ argocd app create APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion + --source-name string Name of the source from the list of sources of the app. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) --sync-retry-backoff-factor int Factor multiplies the base duration after each failed sync retry (default 2) --sync-retry-backoff-max-duration duration Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s) --sync-retry-limit int Max number of allowed sync retries + --sync-source-branch string The branch from which the app will sync + --sync-source-path string The path in the repository from which the app will sync --upsert Allows to override application with the same name even if supplied application spec is different from existing spec --validate Validation of repo and cluster (default true) --values stringArray Helm values file(s) to use @@ -125,6 +134,7 @@ argocd app create APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_delete-resource.md b/docs/user-guide/commands/argocd_app_delete-resource.md index 892de087ec811..085bd89b13240 100644 --- a/docs/user-guide/commands/argocd_app_delete-resource.md +++ b/docs/user-guide/commands/argocd_app_delete-resource.md @@ -43,6 +43,7 @@ argocd app delete-resource APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_delete.md b/docs/user-guide/commands/argocd_app_delete.md index 15ccb486220ad..a7c123f945a3c 100644 --- a/docs/user-guide/commands/argocd_app_delete.md +++ b/docs/user-guide/commands/argocd_app_delete.md @@ -58,6 +58,7 @@ argocd app delete APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_diff.md b/docs/user-guide/commands/argocd_app_diff.md index 07efe70af6b40..743fa6e2b203d 100644 --- a/docs/user-guide/commands/argocd_app_diff.md +++ b/docs/user-guide/commands/argocd_app_diff.md @@ -19,7 +19,8 @@ argocd app diff APPNAME [flags] ``` -N, --app-namespace string Only render the difference in namespace - --exit-code Return non-zero exit code when there is a diff (default true) + --diff-exit-code int Return specified exit code when there is a diff. Typical error code is 20. (default 1) + --exit-code Return non-zero exit code when there is a diff. May also return non-zero exit code if there is an error. (default true) --hard-refresh Refresh application data as well as target manifests cache -h, --help help for diff --ignore-normalizer-jq-execution-timeout duration Set ignore normalizer JQ execution timeout (default 1s) @@ -30,6 +31,7 @@ argocd app diff APPNAME [flags] --revision string Compare live app to a particular revision --revisions stringArray Show manifests at specific revisions for source position in source-positions --server-side-generate Used with --local, this will send your manifests to the server for diffing + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) ``` @@ -54,6 +56,7 @@ argocd app diff APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index 684e77e12ce5a..adbc3cf8ba461 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -36,6 +36,7 @@ argocd app edit APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index 8785e5b52637b..667978ee27c85 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -29,6 +29,9 @@ argocd app get APPNAME [flags] # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app argocd app get my-app --show-params --source-position 1 + # Show application parameters and overrides for a source named "test" + argocd app get my-app --show-params --source-name test + # Refresh application data when retrieving argocd app get my-app --refresh @@ -52,6 +55,7 @@ argocd app get APPNAME [flags] --refresh Refresh application data when retrieving --show-operation Show application operation --show-params Show application parameters and overrides + --source-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) ``` @@ -76,6 +80,7 @@ argocd app get APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_history.md b/docs/user-guide/commands/argocd_app_history.md index 81c2127ab8d6c..e870a6e6cb4c5 100644 --- a/docs/user-guide/commands/argocd_app_history.md +++ b/docs/user-guide/commands/argocd_app_history.md @@ -37,6 +37,7 @@ argocd app history APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_list.md b/docs/user-guide/commands/argocd_app_list.md index 843716f549771..9fb2b8dc32b88 100644 --- a/docs/user-guide/commands/argocd_app_list.md +++ b/docs/user-guide/commands/argocd_app_list.md @@ -55,6 +55,7 @@ argocd app list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_logs.md b/docs/user-guide/commands/argocd_app_logs.md index decb6b05fd808..6d7d9159b0ad6 100644 --- a/docs/user-guide/commands/argocd_app_logs.md +++ b/docs/user-guide/commands/argocd_app_logs.md @@ -86,6 +86,7 @@ argocd app logs APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_manifests.md b/docs/user-guide/commands/argocd_app_manifests.md index 3238a7cfcf2d3..e2cbe3bfb8c7a 100644 --- a/docs/user-guide/commands/argocd_app_manifests.md +++ b/docs/user-guide/commands/argocd_app_manifests.md @@ -17,6 +17,9 @@ argocd app manifests APPNAME [flags] # Get manifests for an application at a specific revision argocd app manifests my-app --revision 0.0.1 + # Get manifests for a multi-source application at specific revisions for specific sources + argocd app manifests my-app --revisions 0.0.1 --source-names src-base --revisions 0.0.2 --source-names src-values + # Get manifests for a multi-source application at specific revisions for specific sources argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 ``` @@ -30,6 +33,7 @@ argocd app manifests APPNAME [flags] --revision string Show manifests at a specific revision --revisions stringArray Show manifests at specific revisions for the source at position in source-positions --source string Source of manifests. One of: live|git (default "git") + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) ``` @@ -54,6 +58,7 @@ argocd app manifests APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_patch-resource.md b/docs/user-guide/commands/argocd_app_patch-resource.md index 392c3c87e7014..6e1f5a1f07485 100644 --- a/docs/user-guide/commands/argocd_app_patch-resource.md +++ b/docs/user-guide/commands/argocd_app_patch-resource.md @@ -43,6 +43,7 @@ argocd app patch-resource APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_patch.md b/docs/user-guide/commands/argocd_app_patch.md index 90375448ce3af..2ae3cb66450ef 100644 --- a/docs/user-guide/commands/argocd_app_patch.md +++ b/docs/user-guide/commands/argocd_app_patch.md @@ -48,6 +48,7 @@ argocd app patch APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index d9741e108ce86..2b0aa9ec29841 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -2,7 +2,7 @@ ## argocd app remove-source -Remove a source from multiple sources application. Counting starts with 1. Default value is -1. +Remove a source from multiple sources application. ``` argocd app remove-source APPNAME [flags] @@ -13,6 +13,9 @@ argocd app remove-source APPNAME [flags] ``` # Remove the source at position 1 from application's sources. Counting starts at 1. argocd app remove-source myapplication --source-position 1 + + # Remove the source named "test" from application's sources. + argocd app remove-source myapplication --source-name test ``` ### Options @@ -20,6 +23,7 @@ argocd app remove-source APPNAME [flags] ``` -N, --app-namespace string Namespace of the target application where the source will be appended -h, --help help for remove-source + --source-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) ``` @@ -44,6 +48,7 @@ argocd app remove-source APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_resources.md b/docs/user-guide/commands/argocd_app_resources.md index 9e3b43c5e1bfa..52e8a21add314 100644 --- a/docs/user-guide/commands/argocd_app_resources.md +++ b/docs/user-guide/commands/argocd_app_resources.md @@ -38,6 +38,7 @@ argocd app resources APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_rollback.md b/docs/user-guide/commands/argocd_app_rollback.md index 47adea4a19a3a..b79761ad04152 100644 --- a/docs/user-guide/commands/argocd_app_rollback.md +++ b/docs/user-guide/commands/argocd_app_rollback.md @@ -39,6 +39,7 @@ argocd app rollback APPNAME [ID] [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 878d6e098e3ca..f877155d3ea7e 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -20,6 +20,9 @@ argocd app set APPNAME [flags] # Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set and override application parameters for a source named "test" under spec.sources of app my-app. + argocd app set my-app --source-name test --repo https://github.com/argoproj/argocd-example-apps.git + # Set application parameters and specify the namespace argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace ``` @@ -37,6 +40,9 @@ argocd app set APPNAME [flags] --directory-exclude string Set glob expression used to exclude files from application source path --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory + --dry-source-path string Path in repository to the app directory for the dry source + --dry-source-repo string Repository URL of the app dry source + --dry-source-revision string Revision of the app dry source --env string Application environment to monitor --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name @@ -47,8 +53,11 @@ argocd app set APPNAME [flags] --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) --helm-set-string stringArray Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2) --helm-skip-crds Skip helm crd installation step + --helm-skip-schema-validation Skip helm schema validation step + --helm-skip-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for set + --hydrate-to-branch string The branch to hydrate the app to --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values --jsonnet-ext-var-code stringArray Jsonnet ext var --jsonnet-ext-var-str stringArray Jsonnet string ext var @@ -78,6 +87,7 @@ argocd app set APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated + --source-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) @@ -85,6 +95,8 @@ argocd app set APPNAME [flags] --sync-retry-backoff-factor int Factor multiplies the base duration after each failed sync retry (default 2) --sync-retry-backoff-max-duration duration Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h) (default 3m0s) --sync-retry-limit int Max number of allowed sync retries + --sync-source-branch string The branch from which the app will sync + --sync-source-path string The path in the repository from which the app will sync --validate Validation of repo and cluster (default true) --values stringArray Helm values file(s) to use --values-literal-file string Filename or URL to import as a literal Helm values block @@ -111,6 +123,7 @@ argocd app set APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index 00d37d33747ff..0a59bc8229334 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -25,7 +25,8 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)' # Sync a multi-source application for specific revision of specific sources - argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-names my-chart --revisions 0.0.2 --source-names my-values # Sync a specific resource # Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME @@ -67,6 +68,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] --revisions stringArray Show manifests at specific revisions for source position in source-positions -l, --selector string Sync apps that match this label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints. --server-side Use server-side apply while syncing the application + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) --strategy string Sync strategy (one of: apply|hook) --timeout uint Time out after this many seconds @@ -93,6 +95,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_terminate-op.md b/docs/user-guide/commands/argocd_app_terminate-op.md index 37cf70b9ea058..9f2dc0b75b59a 100644 --- a/docs/user-guide/commands/argocd_app_terminate-op.md +++ b/docs/user-guide/commands/argocd_app_terminate-op.md @@ -35,6 +35,7 @@ argocd app terminate-op APPNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 177f1b095dd69..a4ff76356539c 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -20,6 +20,9 @@ argocd app unset APPNAME parameters [flags] # Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app unset my-app --source-position 1 --namesuffix + # Unset kustomize override suffix for source named "test" under spec.sources of app my-app. + argocd app unset my-app --source-name test --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM ``` @@ -66,6 +69,7 @@ argocd app unset APPNAME parameters [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_app_wait.md b/docs/user-guide/commands/argocd_app_wait.md index 867484e3432b1..1d706d1c660e6 100644 --- a/docs/user-guide/commands/argocd_app_wait.md +++ b/docs/user-guide/commands/argocd_app_wait.md @@ -43,6 +43,7 @@ argocd app wait [APPNAME.. | -l selector] [flags] --delete Wait for delete --health Wait for health -h, --help help for wait + --hydrated Wait for hydration operations --operation Wait for pending operations -o, --output string Output format. One of: json|yaml|wide|tree|tree=detailed (default "wide") --resource stringArray Sync only specific resources as GROUP:KIND:NAME or !GROUP:KIND:NAME. Fields may be blank and '*' can be used. This option may be specified repeatedly @@ -73,6 +74,7 @@ argocd app wait [APPNAME.. | -l selector] [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset.md b/docs/user-guide/commands/argocd_appset.md index 39c25dcca8fa7..ec704ff00e456 100644 --- a/docs/user-guide/commands/argocd_appset.md +++ b/docs/user-guide/commands/argocd_appset.md @@ -70,6 +70,7 @@ argocd appset [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset_create.md b/docs/user-guide/commands/argocd_appset_create.md index ac0b1427dd7af..2be58b2fef27a 100644 --- a/docs/user-guide/commands/argocd_appset_create.md +++ b/docs/user-guide/commands/argocd_appset_create.md @@ -48,6 +48,7 @@ argocd appset create [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset_delete.md b/docs/user-guide/commands/argocd_appset_delete.md index 90510a42073c0..ffe684cfcc026 100644 --- a/docs/user-guide/commands/argocd_appset_delete.md +++ b/docs/user-guide/commands/argocd_appset_delete.md @@ -43,6 +43,7 @@ argocd appset delete [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset_generate.md b/docs/user-guide/commands/argocd_appset_generate.md index 8c7db6e8ac9c0..a4d94b4ee819e 100644 --- a/docs/user-guide/commands/argocd_appset_generate.md +++ b/docs/user-guide/commands/argocd_appset_generate.md @@ -43,6 +43,7 @@ argocd appset generate [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset_get.md b/docs/user-guide/commands/argocd_appset_get.md index 76b3e3946988b..77229585df316 100644 --- a/docs/user-guide/commands/argocd_appset_get.md +++ b/docs/user-guide/commands/argocd_appset_get.md @@ -44,6 +44,7 @@ argocd appset get APPSETNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_appset_list.md b/docs/user-guide/commands/argocd_appset_list.md index fad42ce7e240c..94cf39b238f68 100644 --- a/docs/user-guide/commands/argocd_appset_list.md +++ b/docs/user-guide/commands/argocd_appset_list.md @@ -46,6 +46,7 @@ argocd appset list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cert.md b/docs/user-guide/commands/argocd_cert.md index 1e0db72b0452b..06e7ce3635f61 100644 --- a/docs/user-guide/commands/argocd_cert.md +++ b/docs/user-guide/commands/argocd_cert.md @@ -77,6 +77,7 @@ argocd cert [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cert_add-ssh.md b/docs/user-guide/commands/argocd_cert_add-ssh.md index a32d12e18ea32..0f0ded047c148 100644 --- a/docs/user-guide/commands/argocd_cert_add-ssh.md +++ b/docs/user-guide/commands/argocd_cert_add-ssh.md @@ -38,6 +38,7 @@ argocd cert add-ssh --batch [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cert_add-tls.md b/docs/user-guide/commands/argocd_cert_add-tls.md index 0208a502836ac..5f632b5be87fc 100644 --- a/docs/user-guide/commands/argocd_cert_add-tls.md +++ b/docs/user-guide/commands/argocd_cert_add-tls.md @@ -37,6 +37,7 @@ argocd cert add-tls SERVERNAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cert_list.md b/docs/user-guide/commands/argocd_cert_list.md index d3b80dfeac97f..be1dc138b1d10 100644 --- a/docs/user-guide/commands/argocd_cert_list.md +++ b/docs/user-guide/commands/argocd_cert_list.md @@ -39,6 +39,7 @@ argocd cert list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cert_rm.md b/docs/user-guide/commands/argocd_cert_rm.md index f76fb6a9a38c9..e88c116da61c5 100644 --- a/docs/user-guide/commands/argocd_cert_rm.md +++ b/docs/user-guide/commands/argocd_cert_rm.md @@ -37,6 +37,7 @@ argocd cert rm REPOSERVER [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster.md b/docs/user-guide/commands/argocd_cluster.md index 6f30e5a9308e4..a7610f3bbbd2f 100644 --- a/docs/user-guide/commands/argocd_cluster.md +++ b/docs/user-guide/commands/argocd_cluster.md @@ -74,6 +74,7 @@ argocd cluster [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_add.md b/docs/user-guide/commands/argocd_cluster_add.md index cf1d9ba2d588e..5758aafd65e40 100644 --- a/docs/user-guide/commands/argocd_cluster_add.md +++ b/docs/user-guide/commands/argocd_cluster_add.md @@ -17,6 +17,7 @@ argocd cluster add CONTEXT [flags] --aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain. --cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'. --cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty. + --disable-compression Bypasses automatic GZip compression requests to the server --exec-command string Command to run to provide client credentials to the cluster. You may need to build a custom ArgoCD image to ensure the command is available at runtime. --exec-command-api-version string Preferred input version of the ExecInfo for the --exec-command executable --exec-command-args stringArray Arguments to supply to the --exec-command executable @@ -29,6 +30,7 @@ argocd cluster add CONTEXT [flags] --name string Overwrite the cluster name --namespace stringArray List of namespaces which are allowed to manage --project string project of the cluster + --proxy-url string use proxy to connect cluster --service-account string System namespace service account to use for kubernetes resource management. If not set then default "argocd-manager" SA will be created --shard int Cluster shard number; inferred from hostname if not set (default -1) --system-namespace string Use different system namespace (default "kube-system") @@ -57,6 +59,7 @@ argocd cluster add CONTEXT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_get.md b/docs/user-guide/commands/argocd_cluster_get.md index 8b3fd5e410a04..f2d9f83833a4e 100644 --- a/docs/user-guide/commands/argocd_cluster_get.md +++ b/docs/user-guide/commands/argocd_cluster_get.md @@ -43,6 +43,7 @@ argocd cluster get in-cluster --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_list.md b/docs/user-guide/commands/argocd_cluster_list.md index d7ffbeb7baa9f..eca386c105b94 100644 --- a/docs/user-guide/commands/argocd_cluster_list.md +++ b/docs/user-guide/commands/argocd_cluster_list.md @@ -58,6 +58,7 @@ argocd cluster list -o server --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_rm.md b/docs/user-guide/commands/argocd_cluster_rm.md index 667e5f9143cd4..d8b0caa10fd63 100644 --- a/docs/user-guide/commands/argocd_cluster_rm.md +++ b/docs/user-guide/commands/argocd_cluster_rm.md @@ -43,6 +43,7 @@ argocd cluster rm cluster-name --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_rotate-auth.md b/docs/user-guide/commands/argocd_cluster_rotate-auth.md index f91c10f3ea6e2..5f913ee491dfa 100644 --- a/docs/user-guide/commands/argocd_cluster_rotate-auth.md +++ b/docs/user-guide/commands/argocd_cluster_rotate-auth.md @@ -42,6 +42,7 @@ argocd cluster rotate-auth cluster-name --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_cluster_set.md b/docs/user-guide/commands/argocd_cluster_set.md index 3d26a6ec29702..42e50727b25a2 100644 --- a/docs/user-guide/commands/argocd_cluster_set.md +++ b/docs/user-guide/commands/argocd_cluster_set.md @@ -47,6 +47,7 @@ argocd cluster set NAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_completion.md b/docs/user-guide/commands/argocd_completion.md index 32c91ccbc2707..f416b13b6457b 100644 --- a/docs/user-guide/commands/argocd_completion.md +++ b/docs/user-guide/commands/argocd_completion.md @@ -70,6 +70,7 @@ $ source ~/.config/fish/completions/argocd.fish --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_configure.md b/docs/user-guide/commands/argocd_configure.md new file mode 100644 index 0000000000000..bfe7a08482eaf --- /dev/null +++ b/docs/user-guide/commands/argocd_configure.md @@ -0,0 +1,80 @@ +# `argocd configure` Command Reference + +## argocd configure + +Manage local configuration + +``` +argocd configure [flags] +``` + +### Examples + +``` +# Enable optional interactive prompts +argocd configure --prompts-enabled +argocd configure --prompts-enabled=true + +# Disable optional interactive prompts +argocd configure --prompts-enabled=false +``` + +### Options + +``` + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for configure + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --prompts-enabled Enable (or disable) optional interactive prompts + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server +``` + +### Options inherited from parent commands + +``` + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server string Argo CD server address + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd](argocd.md) - argocd controls a Argo CD server + diff --git a/docs/user-guide/commands/argocd_context.md b/docs/user-guide/commands/argocd_context.md index 1805bb7e0a1e0..bcc0eda18505f 100644 --- a/docs/user-guide/commands/argocd_context.md +++ b/docs/user-guide/commands/argocd_context.md @@ -49,6 +49,7 @@ argocd context cd.argoproj.io --delete --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_gpg.md b/docs/user-guide/commands/argocd_gpg.md index 41941b1f2739c..534d2ce271e60 100644 --- a/docs/user-guide/commands/argocd_gpg.md +++ b/docs/user-guide/commands/argocd_gpg.md @@ -54,6 +54,7 @@ argocd gpg [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index e0fd7ac55116f..e01bb7b8739eb 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -43,6 +43,7 @@ argocd gpg add [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_gpg_get.md b/docs/user-guide/commands/argocd_gpg_get.md index 5e738b60d8906..f3e254ed74427 100644 --- a/docs/user-guide/commands/argocd_gpg_get.md +++ b/docs/user-guide/commands/argocd_gpg_get.md @@ -49,6 +49,7 @@ argocd gpg get KEYID [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_gpg_list.md b/docs/user-guide/commands/argocd_gpg_list.md index 2d193caf677a6..aa9e1fca92ccb 100644 --- a/docs/user-guide/commands/argocd_gpg_list.md +++ b/docs/user-guide/commands/argocd_gpg_list.md @@ -49,6 +49,7 @@ argocd gpg list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_gpg_rm.md b/docs/user-guide/commands/argocd_gpg_rm.md index 125f193bb473c..be828da1a753d 100644 --- a/docs/user-guide/commands/argocd_gpg_rm.md +++ b/docs/user-guide/commands/argocd_gpg_rm.md @@ -35,6 +35,7 @@ argocd gpg rm KEYID [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_login.md b/docs/user-guide/commands/argocd_login.md index c20247b01b283..5ea61dd623fcf 100644 --- a/docs/user-guide/commands/argocd_login.md +++ b/docs/user-guide/commands/argocd_login.md @@ -59,6 +59,7 @@ argocd login cd.argoproj.io --core --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_logout.md b/docs/user-guide/commands/argocd_logout.md index 132e73fa5033f..6caa721c7a44f 100644 --- a/docs/user-guide/commands/argocd_logout.md +++ b/docs/user-guide/commands/argocd_logout.md @@ -48,6 +48,7 @@ $ argocd logout --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj.md b/docs/user-guide/commands/argocd_proj.md index 8f35188d33634..dabcf668c4fa4 100644 --- a/docs/user-guide/commands/argocd_proj.md +++ b/docs/user-guide/commands/argocd_proj.md @@ -70,6 +70,7 @@ argocd proj [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-destination-service-account.md b/docs/user-guide/commands/argocd_proj_add-destination-service-account.md index b1c0be6de7c85..e08f7ae0e9e72 100644 --- a/docs/user-guide/commands/argocd_proj_add-destination-service-account.md +++ b/docs/user-guide/commands/argocd_proj_add-destination-service-account.md @@ -46,6 +46,7 @@ argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACC --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-destination.md b/docs/user-guide/commands/argocd_proj_add-destination.md index d13f1a5234f7b..c4c166cb97863 100644 --- a/docs/user-guide/commands/argocd_proj_add-destination.md +++ b/docs/user-guide/commands/argocd_proj_add-destination.md @@ -46,6 +46,7 @@ argocd proj add-destination PROJECT SERVER/NAME NAMESPACE [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md b/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md index c32ba8c010300..68a62f86fcf26 100644 --- a/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md @@ -46,6 +46,7 @@ argocd proj add-orphaned-ignore PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-signature-key.md b/docs/user-guide/commands/argocd_proj_add-signature-key.md index 406f554b61195..6c560fdf2a945 100644 --- a/docs/user-guide/commands/argocd_proj_add-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_add-signature-key.md @@ -42,6 +42,7 @@ argocd proj add-signature-key PROJECT KEY-ID [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-source-namespace.md b/docs/user-guide/commands/argocd_proj_add-source-namespace.md index 45c4b0cba6781..eba3d46dd29d7 100644 --- a/docs/user-guide/commands/argocd_proj_add-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_add-source-namespace.md @@ -42,6 +42,7 @@ argocd proj add-source-namespace PROJECT NAMESPACE [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_add-source.md b/docs/user-guide/commands/argocd_proj_add-source.md index 0e64e29d0a3f4..7d5d5b15d322a 100644 --- a/docs/user-guide/commands/argocd_proj_add-source.md +++ b/docs/user-guide/commands/argocd_proj_add-source.md @@ -42,6 +42,7 @@ argocd proj add-source PROJECT URL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md b/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md index 11a8cfc158ff0..0e8be1db34aeb 100644 --- a/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md @@ -43,6 +43,7 @@ argocd proj allow-cluster-resource PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md b/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md index 89bb7197cf2bc..b20ddaeee8c38 100644 --- a/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md @@ -43,6 +43,7 @@ argocd proj allow-namespace-resource PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_create.md b/docs/user-guide/commands/argocd_proj_create.md index c8b27e35bb762..e0c67c4341d06 100644 --- a/docs/user-guide/commands/argocd_proj_create.md +++ b/docs/user-guide/commands/argocd_proj_create.md @@ -27,6 +27,7 @@ argocd proj create PROJECT [flags] --deny-namespaced-resource stringArray List of denied namespaced resources --description string Project description -d, --dest stringArray Permitted destination server and namespace (e.g. https://192.168.99.100:8443,default) + --dest-service-accounts stringArray Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa) -f, --file string Filename or URL to Kubernetes manifests for the project -h, --help help for create --orphaned-resources Enables orphaned resources monitoring @@ -58,6 +59,7 @@ argocd proj create PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_delete.md b/docs/user-guide/commands/argocd_proj_delete.md index b955732eb6067..a6dbd082087f2 100644 --- a/docs/user-guide/commands/argocd_proj_delete.md +++ b/docs/user-guide/commands/argocd_proj_delete.md @@ -42,6 +42,7 @@ argocd proj delete PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md b/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md index bc9bfcfae0d5a..e32e517366758 100644 --- a/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md @@ -43,6 +43,7 @@ argocd proj deny-cluster-resource PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md b/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md index 97367b23cb9c7..fd4214de5b32d 100644 --- a/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md @@ -43,6 +43,7 @@ argocd proj deny-namespace-resource PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_edit.md b/docs/user-guide/commands/argocd_proj_edit.md index 1955aa11ba2c4..c6258e6a40541 100644 --- a/docs/user-guide/commands/argocd_proj_edit.md +++ b/docs/user-guide/commands/argocd_proj_edit.md @@ -42,6 +42,7 @@ argocd proj edit PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_get.md b/docs/user-guide/commands/argocd_proj_get.md index 930972018db05..174085dbe4827 100644 --- a/docs/user-guide/commands/argocd_proj_get.md +++ b/docs/user-guide/commands/argocd_proj_get.md @@ -46,6 +46,7 @@ argocd proj get PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_list.md b/docs/user-guide/commands/argocd_proj_list.md index 2a71f43d68c3a..a64529f40b304 100644 --- a/docs/user-guide/commands/argocd_proj_list.md +++ b/docs/user-guide/commands/argocd_proj_list.md @@ -46,6 +46,7 @@ argocd proj list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-destination-service-account.md b/docs/user-guide/commands/argocd_proj_remove-destination-service-account.md index bcb2a2bc3605e..4759c7874f7b3 100644 --- a/docs/user-guide/commands/argocd_proj_remove-destination-service-account.md +++ b/docs/user-guide/commands/argocd_proj_remove-destination-service-account.md @@ -42,6 +42,7 @@ argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-destination.md b/docs/user-guide/commands/argocd_proj_remove-destination.md index 88a702b2ed2b5..fa1f8f3ded5e9 100644 --- a/docs/user-guide/commands/argocd_proj_remove-destination.md +++ b/docs/user-guide/commands/argocd_proj_remove-destination.md @@ -42,6 +42,7 @@ argocd proj remove-destination PROJECT SERVER NAMESPACE [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md b/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md index 79ff167f1c394..3bb0efc7fd2e6 100644 --- a/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md @@ -46,6 +46,7 @@ argocd proj remove-orphaned-ignore PROJECT GROUP KIND [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-signature-key.md b/docs/user-guide/commands/argocd_proj_remove-signature-key.md index 0f81b6ec52270..55f97f35963f4 100644 --- a/docs/user-guide/commands/argocd_proj_remove-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_remove-signature-key.md @@ -42,6 +42,7 @@ argocd proj remove-signature-key PROJECT KEY-ID [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-source-namespace.md b/docs/user-guide/commands/argocd_proj_remove-source-namespace.md index a26bebcee38bb..32b886452f783 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_remove-source-namespace.md @@ -42,6 +42,7 @@ argocd proj remove-source-namespace PROJECT NAMESPACE [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_remove-source.md b/docs/user-guide/commands/argocd_proj_remove-source.md index 66c016fadd7e5..fa82af4de5ec4 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source.md +++ b/docs/user-guide/commands/argocd_proj_remove-source.md @@ -42,6 +42,7 @@ argocd proj remove-source PROJECT URL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role.md b/docs/user-guide/commands/argocd_proj_role.md index 89d7abe87de4d..569d5a018d066 100644 --- a/docs/user-guide/commands/argocd_proj_role.md +++ b/docs/user-guide/commands/argocd_proj_role.md @@ -35,6 +35,7 @@ argocd proj role [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_add-group.md b/docs/user-guide/commands/argocd_proj_role_add-group.md index 9d818665cd487..358a7b577c75d 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-group.md +++ b/docs/user-guide/commands/argocd_proj_role_add-group.md @@ -35,6 +35,7 @@ argocd proj role add-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_add-policy.md b/docs/user-guide/commands/argocd_proj_role_add-policy.md index d37469d1f8d36..a9bf86afb8be8 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_add-policy.md @@ -67,6 +67,7 @@ ID ISSUED-AT EXPIRES-AT --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_create-token.md b/docs/user-guide/commands/argocd_proj_role_create-token.md index faacc8a01b72d..cc2fbc5669378 100644 --- a/docs/user-guide/commands/argocd_proj_role_create-token.md +++ b/docs/user-guide/commands/argocd_proj_role_create-token.md @@ -50,6 +50,7 @@ Create token succeeded for proj:test-project:test-role. --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_create.md b/docs/user-guide/commands/argocd_proj_role_create.md index 885c79f1672b3..183ca1e854587 100644 --- a/docs/user-guide/commands/argocd_proj_role_create.md +++ b/docs/user-guide/commands/argocd_proj_role_create.md @@ -43,6 +43,7 @@ argocd proj role create PROJECT ROLE-NAME [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_delete-token.md b/docs/user-guide/commands/argocd_proj_role_delete-token.md index c9c5a7fc17eca..bab188e943610 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete-token.md +++ b/docs/user-guide/commands/argocd_proj_role_delete-token.md @@ -67,6 +67,7 @@ $ argocd proj role delete-token test-project test-role 1696769937 --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index 97e01627e371a..5db679d6747f4 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -41,6 +41,7 @@ $ argocd proj role delete test-project test-role --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_get.md b/docs/user-guide/commands/argocd_proj_role_get.md index d35b8768b47b2..5355878ae4a1c 100644 --- a/docs/user-guide/commands/argocd_proj_role_get.md +++ b/docs/user-guide/commands/argocd_proj_role_get.md @@ -50,6 +50,7 @@ ID ISSUED-AT EXPIRES-AT --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_list-tokens.md b/docs/user-guide/commands/argocd_proj_role_list-tokens.md index 7df6b0c64e0aa..e8a921c827cb8 100644 --- a/docs/user-guide/commands/argocd_proj_role_list-tokens.md +++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md @@ -46,6 +46,7 @@ fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index 34b62a3cf4beb..f145895481ad9 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -46,6 +46,7 @@ argocd proj role list PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_remove-group.md b/docs/user-guide/commands/argocd_proj_role_remove-group.md index b4db5dee8b882..5e87b5e464108 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-group.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-group.md @@ -35,6 +35,7 @@ argocd proj role remove-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_role_remove-policy.md b/docs/user-guide/commands/argocd_proj_role_remove-policy.md index df0fd403542af..bde77723c161d 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-policy.md @@ -67,6 +67,7 @@ ID ISSUED-AT EXPIRES-AT --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_set.md b/docs/user-guide/commands/argocd_proj_set.md index 7b4d79ff13588..4dde97b5ccd2a 100644 --- a/docs/user-guide/commands/argocd_proj_set.md +++ b/docs/user-guide/commands/argocd_proj_set.md @@ -27,6 +27,7 @@ argocd proj set PROJECT [flags] --deny-namespaced-resource stringArray List of denied namespaced resources --description string Project description -d, --dest stringArray Permitted destination server and namespace (e.g. https://192.168.99.100:8443,default) + --dest-service-accounts stringArray Destination server, namespace and target service account (e.g. https://192.168.99.100:8443,default,default-sa) -h, --help help for set --orphaned-resources Enables orphaned resources monitoring --orphaned-resources-warn Specifies if applications should have a warning condition when orphaned resources detected @@ -56,6 +57,7 @@ argocd proj set PROJECT [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index b02a6772a8582..4b8018ccead44 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -52,6 +52,7 @@ argocd proj windows list --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index beb158b9c6243..c079fa1f69efa 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -66,6 +66,7 @@ argocd proj windows add PROJECT \ --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 2fc4ef2c43390..9807fdf30b351 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -46,6 +46,7 @@ argocd proj windows delete new-project 1 --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md index 011a394b8848a..dd3bcecb721b5 100644 --- a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md @@ -50,6 +50,7 @@ argocd proj windows disable-manual-sync default 0 --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md index 1f51fe038e3b8..3061dd717d8e9 100644 --- a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md @@ -53,6 +53,7 @@ argocd proj windows enable-manual-sync my-app-project --message "Manual sync ini --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index 5f15f34dfe948..a233938e6eab5 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -50,6 +50,7 @@ argocd proj windows list test-project --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_proj_windows_update.md b/docs/user-guide/commands/argocd_proj_windows_update.md index a3405c0650be8..48334affa06a6 100644 --- a/docs/user-guide/commands/argocd_proj_windows_update.md +++ b/docs/user-guide/commands/argocd_proj_windows_update.md @@ -54,6 +54,7 @@ argocd proj windows update PROJECT ID \ --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_relogin.md b/docs/user-guide/commands/argocd_relogin.md index 8891d35b896dd..20f8dfc572253 100644 --- a/docs/user-guide/commands/argocd_relogin.md +++ b/docs/user-guide/commands/argocd_relogin.md @@ -59,6 +59,7 @@ argocd login cd.argoproj.io --core --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repo.md b/docs/user-guide/commands/argocd_repo.md index 3e6548df9a5a7..ac6b1338bc1bb 100644 --- a/docs/user-guide/commands/argocd_repo.md +++ b/docs/user-guide/commands/argocd_repo.md @@ -72,6 +72,7 @@ argocd repo rm https://github.com/yourusername/your-repo.git --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repo_add.md b/docs/user-guide/commands/argocd_repo_add.md index 4abb437cf7bdc..51fbddbb2a5f7 100644 --- a/docs/user-guide/commands/argocd_repo_add.md +++ b/docs/user-guide/commands/argocd_repo_add.md @@ -97,6 +97,7 @@ argocd repo add REPOURL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repo_get.md b/docs/user-guide/commands/argocd_repo_get.md index b28d30e1e0037..dadd40f52b208 100644 --- a/docs/user-guide/commands/argocd_repo_get.md +++ b/docs/user-guide/commands/argocd_repo_get.md @@ -38,6 +38,7 @@ argocd repo get [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repo_list.md b/docs/user-guide/commands/argocd_repo_list.md index 5a13cff85c5fc..9f99be3b3e1e2 100644 --- a/docs/user-guide/commands/argocd_repo_list.md +++ b/docs/user-guide/commands/argocd_repo_list.md @@ -37,6 +37,7 @@ argocd repo list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repo_rm.md b/docs/user-guide/commands/argocd_repo_rm.md index 4b784e0a6d1c1..78142f9a4bf3d 100644 --- a/docs/user-guide/commands/argocd_repo_rm.md +++ b/docs/user-guide/commands/argocd_repo_rm.md @@ -36,6 +36,7 @@ argocd repo rm REPO [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repocreds.md b/docs/user-guide/commands/argocd_repocreds.md index cac91d9700bf5..b8a7388be0acb 100644 --- a/docs/user-guide/commands/argocd_repocreds.md +++ b/docs/user-guide/commands/argocd_repocreds.md @@ -67,6 +67,7 @@ argocd repocreds [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repocreds_add.md b/docs/user-guide/commands/argocd_repocreds_add.md index 39405519def40..d1399fc51fa6a 100644 --- a/docs/user-guide/commands/argocd_repocreds_add.md +++ b/docs/user-guide/commands/argocd_repocreds_add.md @@ -73,6 +73,7 @@ argocd repocreds add REPOURL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repocreds_list.md b/docs/user-guide/commands/argocd_repocreds_list.md index ebcf308bdc766..e5ff56d731251 100644 --- a/docs/user-guide/commands/argocd_repocreds_list.md +++ b/docs/user-guide/commands/argocd_repocreds_list.md @@ -52,6 +52,7 @@ argocd repocreds list [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_repocreds_rm.md b/docs/user-guide/commands/argocd_repocreds_rm.md index 6893bd3dc3db9..d549da3e6e2de 100644 --- a/docs/user-guide/commands/argocd_repocreds_rm.md +++ b/docs/user-guide/commands/argocd_repocreds_rm.md @@ -42,6 +42,7 @@ argocd repocreds rm CREDSURL [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/commands/argocd_version.md b/docs/user-guide/commands/argocd_version.md index bd6505cc1c622..ed6f9bf5f76e4 100644 --- a/docs/user-guide/commands/argocd_version.md +++ b/docs/user-guide/commands/argocd_version.md @@ -74,6 +74,7 @@ argocd version [flags] --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding + --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") diff --git a/docs/user-guide/diff-strategies.md b/docs/user-guide/diff-strategies.md index ffd09660696ac..48cd4893d388d 100644 --- a/docs/user-guide/diff-strategies.md +++ b/docs/user-guide/diff-strategies.md @@ -16,9 +16,11 @@ Argo CD currently has 3 different strategies to calculate diffs: in dryrun mode in order to generate the predicted live state. ## Structured-Merge Diff -*Current Status: [Beta][1] (Since v2.5.0)* -This is diff strategy is automatically used when Server-Side Apply +!!! warning "Beta Feature (Since v2.5.0)" + This feature is in the [Beta][1] stage. It is generally considered stable, but there may be unhandled edge cases. + +This diff strategy is automatically used when Server-Side Apply sync option is enabled. It uses the [structured-merge-diff][2] library used by Kubernetes to calculate diffs based on fields ownership. There are some challenges using this strategy to calculate diffs for CRDs @@ -27,7 +29,9 @@ the community, this strategy is being discontinued in favour of Server-Side Diff. ## Server-Side Diff -*Current Status: [Beta][1] (Since v2.10.0)* + +!!! warning "Beta Feature (Since v2.10.0)" + This feature is in the [Beta][1] stage. It is generally considered stable, but there may be unhandled edge cases. This diff strategy will execute a Server-Side Apply in dryrun mode for each resource of the application. The response of this operation is then diff --git a/docs/user-guide/diffing.md b/docs/user-guide/diffing.md index 7e5b72d97959c..895f330dfc80a 100644 --- a/docs/user-guide/diffing.md +++ b/docs/user-guide/diffing.md @@ -199,3 +199,4 @@ metadata: name: argocd-cmd-params-cm data: ignore.normalizer.jq.timeout: "5s" +``` diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index c768b50835a24..938a1d318c309 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -418,7 +418,7 @@ repoServer: value: /helm-working-dir initContainers: - name: helm-gcp-authentication - image: alpine/helm:3.8.1 + image: alpine/helm:3.16.1 volumeMounts: - name: helm-working-dir mountPath: /helm-working-dir @@ -498,3 +498,43 @@ spec: helm: skipCrds: true ``` + +## Helm `--skip-schema-validation` + +Helm validates the values.yaml file using a values.schema.json file. See [Schema files](https://helm.sh/docs/topics/charts/#schema-files) for details. + +If needed, it is possible to skip the schema validation step with the `helm-skip-schema-validation` flag on the cli: + +```bash +argocd app set helm-guestbook --helm-skip-schema-validation +``` + +Or using declarative syntax: + +```yaml +spec: + source: + helm: + skipSchemaValidation: true +``` + + + +## Helm `--skip-tests` + +By default, Helm includes test manifests when rendering templates. Argo CD currently skips manifests that include hooks not supported by Argo CD, including [Helm test hooks](https://helm.sh/docs/topics/chart_tests/). While this feature covers many testing use cases, it is not totally congruent with --skip-tests, so the --skip-tests option can be used. + +If needed, it is possible to skip the test manifests installation step with the `helm-skip-tests` flag on the cli: + +```bash +argocd app set helm-guestbook --helm-skip-tests +``` + +Or using declarative syntax: + +```yaml +spec: + source: + helm: + skipTests: true # or false +``` \ No newline at end of file diff --git a/docs/user-guide/multiple_sources.md b/docs/user-guide/multiple_sources.md index f9be46d76f8fa..4d7f1f7ea4a3c 100644 --- a/docs/user-guide/multiple_sources.md +++ b/docs/user-guide/multiple_sources.md @@ -70,9 +70,11 @@ spec: ref: values ``` -In the above example, the `prometheus` chart will use the value file from `git.example.gom/org/value-files.git`. -`$values` resolves to the root of the `value-files` repository. The `$values` variable may only be specified at the -beginning of the value file path. +In the above example, the `prometheus` chart will use the value file from `git.example.com/org/value-files.git`. +For Argo to reference the external Git repository containing the value files, you must set the `ref` parameter on +the repository. In the above example, the parameter `ref: values` maps to the variable `$values`, which resolves +to the root of the `value-files` repository. +Note that the `$values` variable can only be used at the beginning of the value file path. If the `path` field is set in the `$values` source, Argo CD will attempt to generate resources from the git repository at that URL. If the `path` field is not set, Argo CD will use the repository solely as a source of value files. diff --git a/docs/user-guide/resource_tracking.md b/docs/user-guide/resource_tracking.md index e62a7c094f4e2..ff43d6d739910 100644 --- a/docs/user-guide/resource_tracking.md +++ b/docs/user-guide/resource_tracking.md @@ -65,6 +65,14 @@ metadata: The advantages of using the tracking id annotation is that there are no clashes any more with other Kubernetes tools and Argo CD is never confused about the owner of a resource. The `annotation+label` can also be used if you want other tools to understand resources managed by Argo CD. +### Installation ID + +If you are managing one cluster using multiple Argo CD instances, you will need to set `installationID` in the Argo CD ConfigMap. This will prevent conflicts between +the different Argo CD instances: + +* Each managed resource will have the annotation `argocd.argoproj.io/tracking-id: ` +* It is possible to have applications with the same name in Argo CD instances without causing conflicts. + ### Non self-referencing annotations When using the tracking method `annotation` or `annotation+label`, Argo CD will consider the resource properties in the annotation (name, namespace, group and kind) to determine whether the resource should be compared against the desired state. If the tracking annotation does not reference the resource it is applied to, the resource will neither affect the application's sync status nor be marked for pruning. diff --git a/docs/user-guide/skip_reconcile.md b/docs/user-guide/skip_reconcile.md index d5eec86a6a866..3018648e79ffb 100644 --- a/docs/user-guide/skip_reconcile.md +++ b/docs/user-guide/skip_reconcile.md @@ -1,7 +1,7 @@ # Skip Application Reconcile -!!! warning "Alpha Feature" - This is an experimental, alpha-quality feature. +!!! warning "Alpha Feature (Since v2.7.0)" + This is an experimental, [alpha-quality](https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#alpha) feature. The primary use case is to provide integration with third party projects. This feature may be removed in future releases or modified in backwards-incompatible ways. diff --git a/docs/user-guide/source-hydrator.md b/docs/user-guide/source-hydrator.md new file mode 100644 index 0000000000000..d5685f21d0e44 --- /dev/null +++ b/docs/user-guide/source-hydrator.md @@ -0,0 +1,192 @@ +# Source Hydrator + +**Current feature state**: Alpha + +Tools like Helm and Kustomize allow users to express their Kubernetes manifests in a more concise and reusable way +(keeping it DRY - Don't Repeat Yourself). However, these tools can obscure the actual Kubernetes manifests that are +applied to the cluster. + +The "rendered manifest pattern" is a way to push the hydrated manifests to git before syncing them to the cluster. This +allows users to see the actual Kubernetes manifests that are applied to the cluster. + +The source hydrator is a feature of Argo CD that allows users to push the hydrated manifests to git before syncing them +to the cluster. + +## Enabling the Source Hydrator + +The source hydrator is disabled by default. + +To enable the source hydrator, you need to enable the "commit server" component and set the `hydrator.enabled` field in +argocd-cmd-params-cm ConfigMap to `"true"`. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm + namespace: argocd +data: + hydrator.enabled: "true" +``` + +!!! important + After updating the ConfigMap, you must restart the Argo CD controller and API server for the changes to take effect. + +If you are using one of the `*-install.yaml` manifests to install Argo CD, you can use the +`*-install-with-hydrator.yaml` version of that file instead. + +For example, + +``` +Without hydrator: https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml +With hydrator: https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install-with-hydrator.yaml +``` + +!!! important + The `*-with-hydrator-install.yaml` manifests will eventually be removed when the source hydrator is either enabled + by default or removed. The upgrade guide will note if the `install-with-hydrator.yaml` manifests are no longer + available. + +## Using the Source Hydrator + +To use the source hydrator, you must first install a push secret. This example uses a GitHub App for authentication, but +you can use [any authentication method that Argo CD supports for repository access](../operator-manual/declarative-setup.md#repositories). + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: my-push-secret + namespace: argocd + labels: + argocd.argoproj.io/secret-type: repository-write +type: Opaque +stringData: + url: "https://github.com" + type: "git" + githubAppID: "" + githubAppInstallationID: "" + githubAppPrivateKey: | + +``` + +The label `argocd.argoproj.io/secret-type: repository-write` causes this Secret to be used for pushing manifests to git +instead of pulling from git. + +Once your push secret is installed, set the `spec.sourceHydrator` field of the Application. For example: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: my-app +spec: + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + path: helm-guestbook + targetRevision: HEAD + syncSource: + targetBranch: environments/dev + path: helm-guestbook +``` + +In this example, the hydrated manifests will be pushed to the `environments/dev` branch of the `argocd-example-apps` +repository. + +!!! important "Project-Scoped Repositories" + + Repository Secrets may contain a `project` field, making the secret only usable by Applications in that project. + The source hydrator only supports project-scoped repositories if all Applications writing to the same repository and + branch are in the same project. If Applications in different projects write to the same repository and branch, the + source hydrator will not be able to use a project-scoped repository secret and will require a global repository + secret. This behavior may change in the future. + +If there are multiple repository-write Secrets available for a repo, the source hydrator will non-deterministically +select one of the matching Secrets and log a warning saying "Found multiple credentials for repoURL". + +## Pushing to a "Staging" Branch + +The source hydrator can be used to push hydrated manifests to a "staging" branch instead of the `syncSource` branch. +This provides a way to prevent the hydrated manifests from being applied to the cluster until some prerequisite +conditions are met (in effect providing a way to handle environment promotion via Pull Requests). + +To use the source hydrator to push to a "staging" branch, set the `spec.sourceHydrator.hydrateTo` field of the +Application. For example: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: my-app +spec: + project: my-project + destination: + server: https://kubernetes.default.svc + namespace: default + sourceHydrator: + drySource: + repoURL: https://github.com/argoproj/argocd-example-apps + path: helm-guestbook + targetRevision: HEAD + syncSource: + targetBranch: environments/dev + path: helm-guestbook + hydrateTo: + targetBranch: environments/dev-next +``` + +In this example, the hydrated manifests will be pushed to the `environments/dev-next` branch, and Argo CD will not sync +the changes until something moves them to the `environments/dev` branch. + +You could use a CI action to move the hydrated manifests from the `hydrateTo` branch to the `syncSource` branch. To +introduce a gating mechanism, you could require a Pull Request to be opened to merge the changes from the `hydrateTo` +branch to the `syncSource` branch. + +Argo CD will only push changes to the `hydrateTo` branch, it will not create a PR or otherwise facilitate moving those +changes to the `syncSource` branch. You will need to use your own tooling to move the changes from the `hydrateTo` +branch to the `syncSource` branch. + +## Limitations + +### Project-Scoped Push Secrets + +If all the Applications for a given destination repo/branch are under the same project, then the hydrator will use any +available project-scoped push secrets. If two Applications for a given repo/branch are in different projects, then the +hydrator will not be able to use a project-scoped push secret and will require a global push secret. + +### Credential Templates + +Credential templates allow a single credential to be used for multiple repositories. The source hydrator does not +currently support credential templates. You will need a separate credential for each repository. + +## Prerequisites + +### Handle Secrets on the Destination Cluster + +Do not use the source hydrator with any tool that injects secrets into your manifests as part of the hydration process +(for example, Helm with SOPS or the Argo CD Vault Plugin). These secrets would be committed to git. Instead, use a +secrets operator that populates the secret values on the destination cluster. + +## Best Practices + +### Make Hydration Deterministic + +The source hydrator should be deterministic. For a given dry source commit, the hydrator should always produce the same +hydrated manifests. This means that the hydrator should not rely on external state or configuration that is not stored +in git. + +Examples of non-deterministic hydration: + +* A Helm chart using unpinned dependencies +* A Helm chart is using a non-deterministic template function such as `randAlphaNum` or `lookup` +* [Config Management Plugins](../operator-manual/config-management-plugins.md) which retrieve non-git state, such as secrets +* Kustomize manifests referencing unpinned remote bases + +### Enable Branch Protection + +Argo CD should be the only thing pushing hydrated manifests to the hydrated branches. To prevent other tools or users +from pushing to the hydrated branches, enable branch protection in your SCM. + +It is best practice to prefix the hydrated branches with a common prefix, such as `environment/`. This makes it easier +to configure branch protection rules on the destination repository. diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index 99f5eba6b85de..206b0b690b0d3 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -27,6 +27,20 @@ The sync-status panel shows that pruning was skipped, and why: The app will be out of sync if Argo CD expects a resource to be pruned. You may wish to use this along with [compare options](compare-options.md). +## Resource Pruning With Confirmation + +Resources such as Namespaces are critical and should not be pruned without confirmation. You can set the `Prune=confirm` +sync option to require manual confirmation before pruning. + +```yaml +metadata: + annotations: + argocd.argoproj.io/sync-options: Prune=confirm +``` + +To confirm the pruning you can use Argo CD UI, CLI or manually apply the `argocd.argoproj.io/deletion-approved: ` +annotation to the application. + ## Disable Kubectl Validation For a certain class of objects, it is necessary to `kubectl apply` them using the `--validate=false` flag. Examples of this are Kubernetes types which uses `RawExtension`, such as [ServiceCatalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/pkg/apis/servicecatalog/v1beta1/types.go#L497). You can do using this annotations: @@ -70,6 +84,20 @@ metadata: argocd.argoproj.io/sync-options: Delete=false ``` +## Resource Deletion With Confirmation + +Resources such as Namespaces are critical and should not be deleted without confirmation. You can set the `Delete=confirm` +sync option to require manual confirmation before deletion. + +```yaml +metadata: + annotations: + argocd.argoproj.io/sync-options: Delete=confirm +``` + +To confirm the deletion you can use Argo CD UI, CLI or manually apply the `argocd.argoproj.io/deletion-approved: ` +annotation to the application. + ## Selective Sync Currently when syncing using auto sync Argo CD applies every object in the application. @@ -220,6 +248,16 @@ metadata: argocd.argoproj.io/sync-options: ServerSideApply=true ``` +If you want to disable ServerSideApply for a specific resource, while it is enabled at the application level, +add the following sync-option annotation in it: + +```yaml +metadata: + annotations: + argocd.argoproj.io/sync-options: ServerSideApply=false +``` + + ServerSideApply can also be used to patch existing resources by providing a partial yaml. For example, if there is a requirement to update just the number of replicas in a given Deployment, the following yaml can be provided to Argo CD: diff --git a/docs/user-guide/sync-waves.md b/docs/user-guide/sync-waves.md index f888ac42be3f9..73ee08221ac6c 100644 --- a/docs/user-guide/sync-waves.md +++ b/docs/user-guide/sync-waves.md @@ -4,9 +4,9 @@ -Argo CD executes a sync operation in a number of steps. At a high-level, there are three phases *pre-sync*, *sync* and *post-sync*. +Argo CD executes a sync operation in a number of steps. At a high-level, there are three phases *pre-sync*, *sync* and *post-sync*. -Within each phase you can have one or more waves, that allows you to ensure certain resources are healthy before subsequent resources are synced. +Within each phase you can have one or more waves, that allows you to ensure certain resources are healthy before subsequent resources are synced. ## How Do I Configure Phases? @@ -32,6 +32,12 @@ metadata: Hooks and resources are assigned to wave zero by default. The wave can be negative, so you can create a wave that runs before all other resources. +### Can Multiple Resources Share the Same Wave? + +Yes, multiple resources can share the same sync-wave value. Resources with the same sync-wave are processed together. + +Within a wave, resources are ordered by their kind (e.g. namespaces first) and then by their name. + ## How Does It Work? When Argo CD starts a sync, it orders the resources in the following precedence: @@ -39,10 +45,10 @@ When Argo CD starts a sync, it orders the resources in the following precedence: * The phase * The wave they are in (lower values first for creation & updation and higher values first for deletion) * 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 +* 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. - + It applies resources in that wave. It repeats this process until all phases and waves are in-sync and healthy. diff --git a/docs/user-guide/sync_windows.md b/docs/user-guide/sync_windows.md index f6bc6b82f8b69..a786d158ffd23 100644 --- a/docs/user-guide/sync_windows.md +++ b/docs/user-guide/sync_windows.md @@ -2,7 +2,31 @@ Sync windows are configurable windows of time where syncs will either be blocked or allowed. These are defined by a kind, which can be either `allow` or `deny`, a `schedule` in cron format and a duration along with one or -more of either `applications`, `namespaces` and `clusters`. Wildcards are supported. These windows affect the running +more of either `applications`, `namespaces` and `clusters`. Wildcards are supported. + +## Relationship between Sync Windows and Applications + +The relationship between Sync Windows and Application resources is many-to-many. This means that an Application resource +may be affected by multiple Sync Windows, and that a single Sync Window definition may apply to multiple Application +resources. + +The relationship between Sync Window and Application is established as part of the definition of Sync Window. +Sync Window definition includes a section defining the Application resources to which it applies. There +are three mechanisms for selecting the Application resources to which a Sync Window applies: + +- By name of Application resource +- By cluster into which resources are installed by Application resource. This is specified by `Application.spec.destination.name` and `.server` fields +- By namespace into which resources are installed by Application resource. This is specified by `Application.spec.destination.namespace` field. + +All three mechanisms allow usage of wildcards. The mechanisms are not mutually exclusive, and all three of them can be used in single +Sync Window definition. + +When multiple selection mechanisms are used, they are effectively `ORed`, meaning that if any of the selector selects the Application, +then the Application is affected by the Sync Window. + +## Effect of Sync Windows + +These windows affect the running of both manual and automated syncs but allow an override for manual syncs which is useful if you are only interested in preventing automated syncs or if you need to temporarily override a window to perform a sync. diff --git a/examples/dashboard.json b/examples/dashboard.json index b21a008456e1a..2e460c8e10fa6 100644 --- a/examples/dashboard.json +++ b/examples/dashboard.json @@ -2883,7 +2883,7 @@ "datasource": { "uid": "$datasource" }, - "expr": "go_memstats_heap_alloc_bytes{job=\"argocd-repo-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_memstats_heap_alloc_bytes{job=\"argocd-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -2968,7 +2968,7 @@ "datasource": { "uid": "$datasource" }, - "expr": "go_goroutines{job=\"argocd-repo-server-metrics\",namespace=~\"$namespace\"}", + "expr": "go_goroutines{job=\"argocd-server-metrics\",namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{pod}}", @@ -3270,7 +3270,7 @@ "datasource": { "uid": "$datasource" }, - "expr": "go_gc_duration_seconds{job=\"argocd-repo-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}", + "expr": "go_gc_duration_seconds{job=\"argocd-server-metrics\", quantile=\"1\", namespace=~\"$namespace\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{pod}}", diff --git a/go.mod b/go.mod index d3b6084f32571..752b221cfb098 100644 --- a/go.mod +++ b/go.mod @@ -4,30 +4,30 @@ go 1.22.0 require ( code.gitea.io/sdk/gitea v0.19.0 - github.com/Azure/kubelogin v0.0.20 - github.com/Masterminds/semver/v3 v3.3.0 + github.com/Azure/kubelogin v0.1.6 + github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/sprig/v3 v3.3.0 github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.33.0 github.com/antonmedv/expr v1.15.1 - github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5 - github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621 + github.com/argoproj/gitops-engine v0.7.1-0.20241216155226-54992bf42431 + github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.55.5 - github.com/bmatcuk/doublestar/v4 v4.6.1 + github.com/bmatcuk/doublestar/v4 v4.7.1 github.com/bombsimon/logrusr/v2 v2.0.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 - github.com/casbin/casbin/v2 v2.100.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.12.0 + github.com/casbin/casbin/v2 v2.102.0 github.com/casbin/govaluate v1.2.0 github.com/cespare/xxhash/v2 v2.3.0 github.com/chainguard-dev/git-urls v1.0.2 github.com/coreos/go-oidc/v3 v3.11.0 - github.com/cyphar/filepath-securejoin v0.3.2 + github.com/cyphar/filepath-securejoin v0.3.5 github.com/dustin/go-humanize v1.0.1 github.com/evanphx/json-patch v5.9.0+incompatible github.com/expr-lang/expr v1.16.9 github.com/felixge/httpsnoop v1.0.4 - github.com/fsnotify/fsnotify v1.7.0 + github.com/fsnotify/fsnotify v1.8.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.12.0 github.com/go-jose/go-jose/v3 v3.0.3 @@ -39,11 +39,11 @@ require ( github.com/gobwas/glob v0.2.3 github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355 github.com/gogo/protobuf v1.3.2 - github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/golang-jwt/jwt/v4 v4.5.1 github.com/golang/protobuf v1.5.4 github.com/google/btree v1.1.3 github.com/google/go-cmp v0.6.0 - github.com/google/go-github/v63 v63.0.0 + github.com/google/go-github/v66 v66.0.0 github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.6.0 @@ -56,43 +56,43 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 github.com/imdario/mergo v0.3.16 github.com/improbable-eng/grpc-web v0.15.0 - github.com/itchyny/gojq v0.12.16 + github.com/itchyny/gojq v0.12.17 github.com/jeremywohl/flatten v1.0.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/ktrysmt/go-bitbucket v0.9.80 + github.com/ktrysmt/go-bitbucket v0.9.81 github.com/mattn/go-isatty v0.0.20 github.com/mattn/go-zglob v0.0.6 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/olekukonko/tablewriter v0.0.5 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/client_golang v1.20.5 github.com/r3labs/diff v1.1.0 - github.com/redis/go-redis/v9 v9.6.1 + github.com/redis/go-redis/v9 v9.7.0 github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/valyala/fasttemplate v1.2.2 - github.com/xanzy/go-gitlab v0.109.0 + github.com/xanzy/go-gitlab v0.114.0 github.com/yuin/gopher-lua v1.1.1 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 - go.opentelemetry.io/otel/sdk v1.30.0 - golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/net v0.29.0 - golang.org/x/oauth2 v0.23.0 - golang.org/x/sync v0.8.0 - golang.org/x/term v0.24.0 - golang.org/x/time v0.6.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 - google.golang.org/grpc v1.66.2 - google.golang.org/protobuf v1.34.2 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 + go.opentelemetry.io/otel/sdk v1.33.0 + golang.org/x/crypto v0.31.0 + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f + golang.org/x/net v0.32.0 + golang.org/x/oauth2 v0.24.0 + golang.org/x/sync v0.10.0 + golang.org/x/term v0.27.0 + golang.org/x/time v0.8.0 + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 + google.golang.org/grpc v1.68.1 + google.golang.org/protobuf v1.35.2 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.31.0 @@ -107,17 +107,17 @@ require ( k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 oras.land/oras-go/v2 v2.5.0 - sigs.k8s.io/controller-runtime v0.19.0 - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 + sigs.k8s.io/controller-runtime v0.19.3 + sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee sigs.k8s.io/yaml v1.4.0 ) require ( dario.cat/mergo v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect github.com/aws/aws-sdk-go-v2/config v1.25.12 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect @@ -137,34 +137,34 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-jose/go-jose/v4 v4.0.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-github/v62 v62.0.0 // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/x448/float16 v0.8.4 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/api v0.132.0 // indirect - google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/tools v0.27.0 // indirect + google.golang.org/api v0.171.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/retry.v1 v1.0.3 // indirect k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect - k8s.io/klog v1.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) require ( - cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect @@ -209,7 +209,7 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect - github.com/golang/glog v1.2.1 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect @@ -217,7 +217,7 @@ require ( github.com/gosimple/unidecode v1.0.1 // indirect github.com/gregdel/pushover v1.2.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect @@ -270,16 +270,15 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.mongodb.org/mongo-driver v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect + go.mongodb.org/mongo-driver v1.17.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.uber.org/automaxprocs v1.5.3 + go.uber.org/automaxprocs v1.6.0 gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/notify v0.1.1 // indirect - google.golang.org/appengine v1.6.8 // 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 @@ -308,7 +307,7 @@ replace ( k8s.io/api => k8s.io/api v0.31.0 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.0 - k8s.io/apimachinery => k8s.io/apimachinery v0.31.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.31.2 k8s.io/apiserver => k8s.io/apiserver v0.31.0 k8s.io/cli-runtime => k8s.io/cli-runtime v0.31.0 k8s.io/client-go => k8s.io/client-go v0.31.0 diff --git a/go.sum b/go.sum index 154feecfb3750..a6ee7fba19107 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,21 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= code.gitea.io/sdk/gitea v0.19.0 h1:8I6s1s4RHgzxiPHhOQdgim1RWIRcr0LVMbHBjBFXq4Y= code.gitea.io/sdk/gitea v0.19.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1 h1:tz19qLF65vuu2ibfTqGVJxG/zZAI27NEIIbvAOQwYbw= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 h1:jp0dGvZ7ZK0mgqnTSClMxa5xuRL7NZgHameVYF6BurY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= @@ -31,10 +34,12 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/Azure/kubelogin v0.0.20 h1:pDJhxzUWk2f/wjYQJFb0Vet7OYrcg6DLx1qj+sbXY70= -github.com/Azure/kubelogin v0.0.20/go.mod h1:QNuYUuwM2lqho9ovG5U/yv3/ZmFbEru3Jluw2ZeKcSk= -github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2 h1:BGX4OiGP9htYSd6M3pAZctcUUSruhIAUVkv2X0Cn9yE= -github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= +github.com/Azure/kubelogin v0.1.6 h1:2TK38wwjODYVWlHuI7wijwGmsigpDkXWmy9eqXBmMnw= +github.com/Azure/kubelogin v0.1.6/go.mod h1:NxlvRs9CambNudRXrk63zpPgG7PHzqZwsn0v82cuFRE= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= @@ -44,8 +49,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -83,10 +88,10 @@ github.com/antonmedv/expr v1.15.1/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4J 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-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5 h1:K/e+NsNmE4BccRu21QpqUxkTHxU9YWjU3M775Ck+V/E= -github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM= -github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621 h1:Yg1nt+D2uDK1SL2jSlfukA4yc7db184TTN7iWy3voRE= -github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ= +github.com/argoproj/gitops-engine v0.7.1-0.20241216155226-54992bf42431 h1:ku0Gzp1dHr7yn83B/xmMrmbB5sJbe32LXaYSDSBd6/c= +github.com/argoproj/gitops-engine v0.7.1-0.20241216155226-54992bf42431/go.mod h1:WsnykM8idYRUnneeT31cM/Fq/ZsjkefCbjiD8ioCJkU= +github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd h1:lOVVoK89j9Nd4+JYJiKAaMNYC1402C0jICROOfUPWn0= +github.com/argoproj/notifications-engine v0.4.1-0.20241007194503-2fef5c9049fd/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -141,12 +146,13 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q= +github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= -github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 h1:R9d0v+iobRHSaE4wKUnXFiZp53AL4ED5MzgEMwGTZag= -github.com/bradleyfalzon/ghinstallation/v2 v2.11.0/go.mod h1:0LWKQwOHewXO/1acI6TtyE0Xc4ObDb2rFN7eHBAG71M= +github.com/bradleyfalzon/ghinstallation/v2 v2.12.0 h1:k8oVjGhZel2qmCUsYwSE34jPNT9DL2wCBOtugsHv26g= +github.com/bradleyfalzon/ghinstallation/v2 v2.12.0/go.mod h1:V4gJcNyAftH0rXpRp1SUVUuh+ACxOH1xOk/ZzkRHltg= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -154,8 +160,8 @@ github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0 github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.100.0 h1:aeugSNjjHfCrgA22nHkVvw2xsscboHv5r0a13ljQKGQ= -github.com/casbin/casbin/v2 v2.100.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng= +github.com/casbin/casbin/v2 v2.102.0 h1:weq9iSThUSL21SH3VrwoKa2DgRsaYMfjRNX/yOU3Foo= +github.com/casbin/casbin/v2 v2.102.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng= github.com/casbin/govaluate v1.2.0 h1:wXCXFmqyY+1RwiKfYo3jMKyrtZmOL3kHwaqDyCPOYak= github.com/casbin/govaluate v1.2.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -204,8 +210,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.3.2 h1:QhZu5AxQ+o1XZH0Ye05YzvJ0kAdK6VQc0z9NNMek7gc= -github.com/cyphar/filepath-securejoin v0.3.2/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= +github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= +github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -222,8 +228,6 @@ github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -269,8 +273,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e h1:C3DkNr9pxqXqCrmRHO7s3XgZS3zpi9GEA01GuWZODfo= @@ -307,7 +311,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -387,15 +390,15 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -434,10 +437,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= -github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= -github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE= -github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA= +github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M= +github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4= github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g= github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -462,10 +463,10 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= -github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -498,8 +499,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -546,8 +547,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/itchyny/gojq v0.12.16 h1:yLfgLxhIr/6sJNVmYfQjTIv0jGctu6/DgDoivmxTr7g= -github.com/itchyny/gojq v0.12.16/go.mod h1:6abHbdC2uB9ogMS38XsErnfqJ94UlngIJGlRAIj4jTM= +github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= +github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= @@ -583,6 +584,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -607,8 +610,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/ktrysmt/go-bitbucket v0.9.80 h1:S+vZTXKx/VG5yCaX4I3Bmwo8lxWr4ifvuHdTboHTMMc= -github.com/ktrysmt/go-bitbucket v0.9.80/go.mod h1:b8ogWEGxQMWoeFnT1ZE4aHIPGindI+9z/zAW/OVFjk0= +github.com/ktrysmt/go-bitbucket v0.9.81 h1:PQxJsFcGdblDOv5PhFA03uNgXMiJfpLo03oYIUdQ2h0= +github.com/ktrysmt/go-bitbucket v0.9.81/go.mod h1:eWIy5+e1l2eDf9xxwCEmK7oPvNKR91vwYocJWIUQISQ= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= @@ -683,7 +686,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -794,9 +796,8 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -814,8 +815,8 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -843,8 +844,8 @@ github.com/r3labs/diff v1.1.0 h1:V53xhrbTHrWFWq3gI4b94AjgEJOerO1+1l0xyHOBi8M= github.com/r3labs/diff v1.1.0/go.mod h1:7WjXasNzi0vJetRcB/RqNl5dlIsmXcTTLmF5IoH6Xig= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.0-rc.4/go.mod h1:Vo3EsyWnicKnSKCA7HhgnvnyA74wOA69Cd2Meli5mmA= -github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= -github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -857,8 +858,9 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -928,8 +930,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -949,8 +952,8 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xanzy/go-gitlab v0.109.0 h1:RcRme5w8VpLXTSTTMZdVoQWY37qTJWg+gwdQl4aAttE= -github.com/xanzy/go-gitlab v0.109.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= +github.com/xanzy/go-gitlab v0.114.0 h1:0wQr/KBckwrZPfEMjRqpUz0HmsKKON9UhCYv9KDy19M= +github.com/xanzy/go-gitlab v0.114.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -964,27 +967,31 @@ github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM= +go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= @@ -993,11 +1000,13 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1040,13 +1049,13 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1070,8 +1079,9 @@ golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1125,16 +1135,16 @@ golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1150,8 +1160,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1189,7 +1199,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1222,8 +1231,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1248,14 +1257,13 @@ golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -1269,13 +1277,13 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1311,8 +1319,9 @@ golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1326,14 +1335,12 @@ gomodules.xyz/notify v0.1.1 h1:1tTuoyswmPvzqPCTEDQK8SZ3ukCxLsonAAwst2+y1a0= gomodules.xyz/notify v0.1.1/go.mod h1:QgQyU4xEA/plJcDeT66J2Go2V7U4c0pD9wjo7HfFil4= gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= -google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1343,12 +1350,12 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1364,8 +1371,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= @@ -1373,8 +1380,9 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -1384,6 +1392,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/dnaeon/go-vcr.v3 v3.2.0 h1:Rltp0Vf+Aq0u4rQXgmXgtgoRDStTnFN83cWgSGSoRzM= +gopkg.in/dnaeon/go-vcr.v3 v3.2.0/go.mod h1:2IMOnnlx9I6u9x+YBsM3tAMx6AlOxnJ0pWxQAzZ79Ag= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= @@ -1412,8 +1422,8 @@ k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= +k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY= k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk= k8s.io/cli-runtime v0.31.0 h1:V2Q1gj1u3/WfhD475HBQrIYsoryg/LrhhK4RwpN+DhA= @@ -1428,8 +1438,6 @@ k8s.io/component-helpers v0.31.0 h1:jyRUKA+GX+q19o81k4x94imjNICn+e6Gzi6T89va1/A= k8s.io/component-helpers v0.31.0/go.mod h1:MrNIvT4iB7wXIseYSWfHUJB/aNUiFvbilp4qDfBQi6s= k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo= k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= @@ -1454,8 +1462,8 @@ nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= +sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= @@ -1463,8 +1471,9 @@ sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZ sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee h1:ipT2c6nEOdAfBwiwW1oI0mkrlPabbXEFmJBrg6B+OR8= +sigs.k8s.io/structured-merge-diff/v4 v4.4.4-0.20241211184406-7bf59b3d70ee/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/hack/gen-resources/generators/application_generator.go b/hack/gen-resources/generators/application_generator.go index 9e78299d979b0..6d7db8c587910 100644 --- a/hack/gen-resources/generators/application_generator.go +++ b/hack/gen-resources/generators/application_generator.go @@ -82,12 +82,12 @@ func (pg *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { if err != nil { return err } - log.Printf("Pick source \"%s\"", source) + log.Printf("Pick source %q", source) destination, err := pg.buildDestination(opts, clusters.Items) if err != nil { return err } - log.Printf("Pick destination \"%s\"", destination) + log.Printf("Pick destination %q", destination) log.Printf("Create application") _, err = applications.Create(context.TODO(), &v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ diff --git a/hack/generate-proto.sh b/hack/generate-proto.sh index 83f542a9d21ab..f4f3cfe17339e 100755 --- a/hack/generate-proto.sh +++ b/hack/generate-proto.sh @@ -95,7 +95,7 @@ MOD_ROOT=${GOPATH}/pkg/mod grpc_gateway_version=$(go list -m github.com/grpc-ecosystem/grpc-gateway | awk '{print $NF}' | head -1) GOOGLE_PROTO_API_PATH=${MOD_ROOT}/github.com/grpc-ecosystem/grpc-gateway@${grpc_gateway_version}/third_party/googleapis GOGO_PROTOBUF_PATH=${PROJECT_ROOT}/vendor/github.com/gogo/protobuf -PROTO_FILES=$(find "$PROJECT_ROOT" \( -name "*.proto" -and -path '*/server/*' -or -path '*/reposerver/*' -and -name "*.proto" -or -path '*/cmpserver/*' -and -name "*.proto" \) | sort) +PROTO_FILES=$(find "$PROJECT_ROOT" \( -name "*.proto" -and -path '*/server/*' -or -path '*/reposerver/*' -and -name "*.proto" -or -path '*/cmpserver/*' -and -name "*.proto" -or -path '*/commitserver/*' -and -name "*.proto" -or -path '*/util/askpass/*' -and -name "*.proto" \) | sort) for i in ${PROTO_FILES}; do protoc \ -I"${PROJECT_ROOT}" \ @@ -110,6 +110,9 @@ for i in ${PROTO_FILES}; do "$i" done +# This file is generated but should not be checked in. +rm util/askpass/askpass.swagger.json + [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" [ -L ./v2 ] && rm -rf v2 @@ -162,3 +165,4 @@ clean_swagger server clean_swagger reposerver clean_swagger controller clean_swagger cmpserver +clean_swagger commitserver diff --git a/hack/get-previous-release/get-previous-version-for-release-notes.go b/hack/get-previous-release/get-previous-version-for-release-notes.go new file mode 100644 index 0000000000000..a322c9fe0b2e4 --- /dev/null +++ b/hack/get-previous-release/get-previous-version-for-release-notes.go @@ -0,0 +1,132 @@ +package main + +import ( + "fmt" + "golang.org/x/mod/semver" + "os" + "os/exec" + "regexp" + "strconv" + "strings" +) + +/** +This script is used to determine the previous version of a release based on the current version. It is used to help +generate release notes for a new release. +*/ + +func main() { + if len(os.Args) < 2 { + fmt.Println("Usage: go run get-previous-version-for-release-notes.go ") + return + } + + proposedTag := os.Args[1] + + tags, err := getGitTags() + if err != nil { + fmt.Printf("Error getting git tags: %v\n", err) + return + } + + previousTag, err := findPreviousTag(proposedTag, tags) + if err != nil { + fmt.Printf("Error finding previous tag: %v\n", err) + os.Exit(1) + } + + fmt.Printf("%s\n", previousTag) +} + +func extractPatchAndRC(tag string) (string, string, error) { + re := regexp.MustCompile(`^v\d+\.\d+\.(\d+)(?:-rc(\d+))?$`) + matches := re.FindStringSubmatch(tag) + if len(matches) < 2 { + return "", "", fmt.Errorf("invalid tag format: %s", tag) + } + patch := matches[1] + rc := "0" + if len(matches) == 3 && matches[2] != "" { + rc = matches[2] + } + return patch, rc, nil +} + +func findPreviousTag(proposedTag string, tags []string) (string, error) { + var previousTag string + proposedMajor := semver.Major(proposedTag) + proposedMinor := semver.MajorMinor(proposedTag) + + proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag) + if err != nil { + return "", err + } + + // If the current tag is a .0 patch release or a 1 release candidate, adjust to the previous minor release series. + if (proposedPatch == "0" && proposedRC == "0") || proposedRC == "1" { + proposedMinorInt, err := strconv.Atoi(strings.TrimPrefix(proposedMinor, proposedMajor+".")) + if err != nil { + return "", fmt.Errorf("invalid minor version: %v", err) + } + if proposedMinorInt > 0 { + proposedMinor = fmt.Sprintf("%s.%d", proposedMajor, proposedMinorInt-1) + } + } + + for _, tag := range tags { + if tag == proposedTag { + continue + } + tagMajor := semver.Major(tag) + tagMinor := semver.MajorMinor(tag) + tagPatch, tagRC, err := extractPatchAndRC(tag) + if err != nil { + continue + } + + // Only bother considering tags with the same major and minor version. + if tagMajor == proposedMajor && tagMinor == proposedMinor { + // If it's a non-RC release... + if proposedRC == "0" { + // Only consider non-RC tags. + if tagRC == "0" { + if semver.Compare(tag, previousTag) > 0 { + previousTag = tag + } + } + } else { + if tagRC != "0" && tagPatch == proposedPatch { + if semver.Compare(tag, previousTag) > 0 { + previousTag = tag + } + } else if tagRC == "0" { + if semver.Compare(tag, previousTag) > 0 { + previousTag = tag + } + } + } + } + } + if previousTag == "" { + return "", fmt.Errorf("no matching tag found for tags: " + strings.Join(tags, ", ")) + } + return previousTag, nil +} + +func getGitTags() ([]string, error) { + cmd := exec.Command("git", "tag", "--sort=-v:refname") + output, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("error executing git command: %v", err) + } + + tags := strings.Split(string(output), "\n") + var semverTags []string + for _, tag := range tags { + if semver.IsValid(tag) { + semverTags = append(semverTags, tag) + } + } + + return semverTags, nil +} diff --git a/hack/get-previous-release/get-previous-version-for-release-notes_test.go b/hack/get-previous-release/get-previous-version-for-release-notes_test.go new file mode 100644 index 0000000000000..b41f33534684b --- /dev/null +++ b/hack/get-previous-release/get-previous-version-for-release-notes_test.go @@ -0,0 +1,93 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindPreviousTagRules(t *testing.T) { + t.Parallel() + // Sample pulled from git tag --sort=-v:refname output. + tags := []string{ + "v2.13.0-rc3", + "v2.13.0-rc2", + "v2.13.0-rc1", + "v2.12.5", + "v2.12.4", + "v2.12.3", + "v2.12.2", + "v2.12.1", + "v2.12.0-rc5", + "v2.12.0-rc4", + "v2.12.0-rc3", + "v2.12.0-rc2", + "v2.12.0-rc1", + "v2.12.0", + "v2.11.11", + "v2.11.10", + "v2.11.9", + "v2.11.8", + "v2.11.7", + "v2.11.6", + "v2.11.5", + "v2.11.4", + "v2.11.3", + "v2.11.2", + "v2.11.1", + "v2.11.0-rc3", + "v2.11.0-rc2", + "v2.11.0-rc1", + "v2.11.0", + "v2.10.17", + "v2.10.16", + "v2.10.15", + "v2.10.14", + "v2.10.13", + "v2.10.12", + "v2.10.11", + "v2.10.10", + "v2.10.9", + "v2.10.8", + "v2.10.7", + "v2.10.6", + "v2.10.5", + "v2.10.4", + "v2.10.3", + "v2.10.2", + "v2.10.1", + "v2.10.0-rc5", + "v2.10.0-rc4", + "v2.10.0-rc3", + "v2.10.0-rc2", + "v2.10.0-rc1", + "v2.10.0", + } + + tests := []struct { + name, proposedTag, expected string + expectError bool + }{ + // Rule 1: If we're releasing a .0 patch release, get the most recent tag on the previous minor release series. + {"Rule 1: .0 patch release", "v2.13.0", "v2.12.5", false}, + // Rule 2: If we're releasing a non-0 patch release, get the most recent tag within the same minor release series. + {"Rule 2: non-0 patch release", "v2.12.6", "v2.12.5", false}, + // Rule 3: If we're releasing a 1 release candidate, get the most recent tag on the previous minor release series. + {"Rule 3: 1 release candidate", "v2.14.0-rc1", "v2.13.0-rc3", false}, + // Rule 4: If we're releasing a non-1 release candidate, get the most recent rc tag on the current minor release series. + {"Rule 4: non-1 release candidate", "v2.13.0-rc4", "v2.13.0-rc3", false}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result, err := findPreviousTag(test.proposedTag, tags) + if test.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equalf(t, test.expected, result, "for proposed tag %s expected %s but got %s", test.proposedTag, test.expected, result) + } + }) + } +} diff --git a/hack/get-previous-release/go.mod b/hack/get-previous-release/go.mod new file mode 100644 index 0000000000000..137bd2b32dea7 --- /dev/null +++ b/hack/get-previous-release/go.mod @@ -0,0 +1,14 @@ +module github.com/argoproj/argo-cd/get-previous-release + +go 1.22.5 + +require ( + github.com/stretchr/testify v1.9.0 + golang.org/x/mod v0.21.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/hack/get-previous-release/go.sum b/hack/get-previous-release/go.sum new file mode 100644 index 0000000000000..ed2a5829b3bbb --- /dev/null +++ b/hack/get-previous-release/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hack/installers/checksums/helm-v-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/hack/installers/checksums/helm-v-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/hack/installers/checksums/helm-v-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/hack/installers/checksums/helm-v-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/hack/installers/checksums/helm-v3.15.4-darwin-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-darwin-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..8857c0720c0c7 --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-darwin-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +1bc3f354f7ce4d7fd9cfa5bcc701c1f32c88d27076d96c2792d5b5226062aee5 helm-v3.15.4-darwin-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.15.4-darwin-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-darwin-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..4ee2beac2ea3f --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-darwin-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +88115846a1fb58f8eb8f64fec5c343d95ca394f1be811602fa54a887c98730ac helm-v3.15.4-darwin-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.15.4-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..5996c0d82cf75 --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +11400fecfc07fd6f034863e4e0c4c4445594673fd2a129e701fe41f31170cfa9 helm-v3.15.4-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.15.4-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..a6954894d20c0 --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +fa419ecb139442e8a594c242343fafb7a46af3af34041c4eac1efcc49d74e626 helm-v3.15.4-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.15.4-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..9292b9dbe2c71 --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +e4efce93723f52dd858e9046ea836c9c75f346facce1b87b8cf78c817b97e6ac helm-v3.15.4-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.15.4-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.15.4-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..040a3b21534c8 --- /dev/null +++ b/hack/installers/checksums/helm-v3.15.4-linux-s390x.tar.gz.sha256 @@ -0,0 +1 @@ +c6e0cdea598196895ac7b627ce972699ef9f06b0eba51dc4db7cc21b3369f24a helm-v3.15.4-linux-s390x.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-darwin-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-darwin-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..e18ebc0a5508a --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-darwin-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +495d75b404a96fb664f1ca3f8cb01db2210aacc62dbfa1bbab30916abbb20a57 helm-v3.16.3-darwin-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-darwin-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-darwin-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..c1aeefe87d609 --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-darwin-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +3a39f690173086e6eea17674751eb3c8b970c02697e49cecd4093eaa3cf89dcd helm-v3.16.3-darwin-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..2d626fb39f280 --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +f5355c79190951eed23c5432a3b920e071f4c00a64f75e077de0dd4cb7b294ea helm-v3.16.3-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..9d0b427069911 --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +5bd34ed774df6914b323ff84a0a156ea6ff2ba1eaf0113962fa773f3f9def798 helm-v3.16.3-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..d57da1739d4d2 --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +266f7698c56a724fddd3a2f2b862ad496c4338dce79f0282fdbc6e23e1738608 helm-v3.16.3-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.16.3-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.16.3-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..1f6019aa2daad --- /dev/null +++ b/hack/installers/checksums/helm-v3.16.3-linux-s390x.tar.gz.sha256 @@ -0,0 +1 @@ +bac414c409faead9c2b8af11d29281aa4f1aeb9139c62d5178baf982d71fc9bb helm-v3.16.3-linux-s390x.tar.gz diff --git a/hack/installers/install-codegen-tools.sh b/hack/installers/install-codegen-tools.sh index f97255d35cca3..884f83f71fbb4 100755 --- a/hack/installers/install-codegen-tools.sh +++ b/hack/installers/install-codegen-tools.sh @@ -1,4 +1,4 @@ #!/bin/bash set -eux -o pipefail -KUSTOMIZE_VERSION=4.5.7 "$(dirname $0)/../install.sh" kustomize protoc +KUSTOMIZE_VERSION=5.4.3 "$(dirname $0)/../install.sh" kustomize protoc diff --git a/hack/installers/install-kustomize.sh b/hack/installers/install-kustomize.sh index 3457d1613243f..c4118aea72aaf 100755 --- a/hack/installers/install-kustomize.sh +++ b/hack/installers/install-kustomize.sh @@ -4,6 +4,7 @@ set -eux -o pipefail . $(dirname $0)/../tool-versions.sh PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/../..; pwd) +INSTALL_PATH="${BIN:-$INSTALL_PATH}" INSTALL_PATH="${INSTALL_PATH:-$PROJECT_ROOT/dist}" PATH="${INSTALL_PATH}:${PATH}" [ -d $INSTALL_PATH ] || mkdir -p $INSTALL_PATH diff --git a/hack/installers/install-lint-tools.sh b/hack/installers/install-lint-tools.sh index 54e7b725478c8..3dbc9e24be8c9 100755 --- a/hack/installers/install-lint-tools.sh +++ b/hack/installers/install-lint-tools.sh @@ -1,4 +1,7 @@ #!/bin/bash set -eux -o pipefail -GO111MODULE=on go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.58.2 +# renovate: datasource=go packageName=github.com/golangci/golangci-lint +GOLANGCI_LINT_VERSION=1.62.2 + +GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}" diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 28ca1cda431da..5ff690de480ad 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,7 +11,7 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.15.2 +helm3_version=3.16.3 kubectl_version=1.17.8 kubectx_version=0.6.3 kustomize5_version=5.4.3 diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index cdd932807d784..a2169c945bd76 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -27,7 +27,7 @@ PATH="${PROJECT_ROOT}/dist:${PATH}" GOPATH=$(go env GOPATH) GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd" -TARGET_SCRIPT=/tmp/kube_codegen.sh +TARGET_SCRIPT=kube_codegen.sh # codegen utilities are installed outside of kube_codegen.sh so remove the `go install` step in the script. sed -e '/go install/d' ${PROJECT_ROOT}/vendor/k8s.io/code-generator/kube_codegen.sh >${TARGET_SCRIPT} @@ -39,11 +39,18 @@ sed -i.bak -e 's#${gobin}/##g' ${TARGET_SCRIPT} [ -e ./v2 ] || ln -s . v2 [ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") -bash -x ${TARGET_SCRIPT} "deepcopy,client,informer,lister" \ - github.com/argoproj/argo-cd/v2/pkg/client github.com/argoproj/argo-cd/v2/pkg/apis \ - "application:v1alpha1" \ - --go-header-file "${PROJECT_ROOT}/hack/custom-boilerplate.go.txt" \ - --output-base "${GOPATH}/src" +# shellcheck source=pkg/apis/application/v1alpha1/kube_codegen.sh +. ${TARGET_SCRIPT} + +kube::codegen::gen_helpers pkg/apis/application/v1alpha1 +kube::codegen::gen_client pkg/apis \ + --output-dir pkg/client \ + --output-pkg github.com/argoproj/argo-cd/v2/pkg/client \ + --boilerplate "${PROJECT_ROOT}/hack/custom-boilerplate.go.txt" \ + --with-watch + +rm ${TARGET_SCRIPT} +rm ${TARGET_SCRIPT}.bak [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" [ -L ./v2 ] && rm -rf v2 diff --git a/hack/update-manifests.sh b/hack/update-manifests.sh index b546fdcf2ce9a..815efbd1c49fd 100755 --- a/hack/update-manifests.sh +++ b/hack/update-manifests.sh @@ -49,3 +49,21 @@ $KUSTOMIZE build "${SRCROOT}/manifests/ha/namespace-install" >> "${SRCROOT}/mani echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/core-install.yaml" $KUSTOMIZE build "${SRCROOT}/manifests/core-install" >> "${SRCROOT}/manifests/core-install.yaml" + +# Copies enabling manifest hydrator. These can be removed once the manifest hydrator is either removed or enabled by +# default. + +echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/install-with-hydrator.yaml" +$KUSTOMIZE build "${SRCROOT}/manifests/cluster-install-with-hydrator" >> "${SRCROOT}/manifests/install-with-hydrator.yaml" + +echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/namespace-install-with-hydrator.yaml" +$KUSTOMIZE build "${SRCROOT}/manifests/namespace-install-with-hydrator" >> "${SRCROOT}/manifests/namespace-install-with-hydrator.yaml" + +echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/ha/install-with-hydrator.yaml" +$KUSTOMIZE build "${SRCROOT}/manifests/ha/cluster-install-with-hydrator" >> "${SRCROOT}/manifests/ha/install-with-hydrator.yaml" + +echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/ha/namespace-install-with-hydrator.yaml" +$KUSTOMIZE build "${SRCROOT}/manifests/ha/namespace-install-with-hydrator" >> "${SRCROOT}/manifests/ha/namespace-install-with-hydrator.yaml" + +echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/core-install-with-hydrator.yaml" +$KUSTOMIZE build "${SRCROOT}/manifests/core-install-with-hydrator" >> "${SRCROOT}/manifests/core-install-with-hydrator.yaml" diff --git a/hack/update-supported-versions.sh b/hack/update-supported-versions.sh old mode 100644 new mode 100755 index f4f10aa31a007..caf327a27fc26 --- a/hack/update-supported-versions.sh +++ b/hack/update-supported-versions.sh @@ -11,7 +11,11 @@ for n in 0 1 2; do minor_version_num=$((argocd_minor_version_num - n)) minor_version="${argocd_major_version_num}.${minor_version_num}" git checkout "release-$minor_version" > /dev/null || exit 1 - line=$(yq '.jobs["test-e2e"].strategy.matrix["k3s-version"][]' .github/workflows/ci-build.yaml | \ + + line=$(yq '.jobs["test-e2e"].strategy.matrix | + # k3s-version was an array prior to 2.12. This checks for the old format first and then falls back to the new format. + (.["k3s-version"] // (.k3s | map(.version))) | + .[]' .github/workflows/ci-build.yaml | \ jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \ 'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"') out+="$line\n" diff --git a/kustomize b/kustomize new file mode 100755 index 0000000000000..1577ba57c1d6c Binary files /dev/null and b/kustomize differ diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 619c4ca4817b8..fbf52943ab706 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -97,6 +97,30 @@ spec: name: argocd-cmd-params-cm key: controller.self.heal.timeout.seconds optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.timeout.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.factor + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.cap.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.sync.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -199,6 +223,12 @@ spec: name: argocd-cmd-params-cm key: controller.diff.server.side optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: hydrator.enabled + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -264,3 +294,5 @@ spec: items: - key: controller.profile.enabled path: profiler.enabled + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index ca09f482c35f7..f576bcc19f59a 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -100,6 +100,30 @@ spec: name: argocd-cmd-params-cm key: controller.self.heal.timeout.seconds optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.timeout.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.factor + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.backoff.cap.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.sync.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -208,6 +232,14 @@ spec: name: argocd-cmd-params-cm key: controller.ignore.normalizer.jq.timeout optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: hydrator.enabled + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -236,6 +268,8 @@ spec: mountPath: /home/argocd - name: argocd-cmd-params-cm mountPath: /home/argocd/params + - name: argocd-application-controller-tmp + mountPath: /tmp serviceAccountName: argocd-application-controller affinity: podAntiAffinity: @@ -255,6 +289,8 @@ spec: volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: secretName: argocd-repo-server-tls @@ -272,4 +308,6 @@ spec: name: argocd-cmd-params-cm items: - key: controller.profile.enabled - path: profiler.enabled \ No newline at end of file + path: profiler.enabled + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml index 6bade745f76c1..f4df48823a5ff 100644 --- a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml +++ b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml @@ -103,6 +103,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -163,6 +169,12 @@ spec: name: argocd-cmd-params-cm key: applicationsetcontroller.webhook.parallelism.limit optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: applicationsetcontroller.requeue.after + optional: true volumeMounts: - mountPath: /app/config/ssh name: ssh-known-hosts @@ -211,3 +223,5 @@ spec: path: tls.key - key: ca.crt path: ca.crt + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/commit-server/argocd-commit-server-deployment.yaml b/manifests/base/commit-server/argocd-commit-server-deployment.yaml new file mode 100644 index 0000000000000..2eba92802080c --- /dev/null +++ b/manifests/base/commit-server/argocd-commit-server-deployment.yaml @@ -0,0 +1,150 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: commit-server + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + serviceAccountName: argocd-commit-server + automountServiceAccountToken: false + containers: + - name: argocd-commit-server + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commitserver.listen.address + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commitserver.metrics.listen.address + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commitserver.log.format + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: commitserver.log.level + optional: true + ports: + - containerPort: 8086 + - containerPort: 8087 + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: ssh-known-hosts + mountPath: /app/config/ssh + - name: tls-certs + mountPath: /app/config/tls + - name: gpg-keys + mountPath: /app/config/gpg/source + - name: gpg-keyring + mountPath: /app/config/gpg/keys + # We need a writeable temp directory for the askpass socket file. + - name: tmp + mountPath: /tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + volumes: + - name: ssh-known-hosts + configMap: + name: argocd-ssh-known-hosts-cm + - name: tls-certs + configMap: + name: argocd-tls-certs-cm + - name: gpg-keys + configMap: + name: argocd-gpg-keys-cm + - name: gpg-keyring + emptyDir: {} + - name: tmp + emptyDir: {} + - name: argocd-commit-server-tls + secret: + secretName: argocd-commit-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + - emptyDir: {} + name: var-files + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + - weight: 5 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname diff --git a/manifests/base/commit-server/argocd-commit-server-network-policy.yaml b/manifests/base/commit-server/argocd-commit-server-network-policy.yaml new file mode 100644 index 0000000000000..119bf985d5ddd --- /dev/null +++ b/manifests/base/commit-server/argocd-commit-server-network-policy.yaml @@ -0,0 +1,22 @@ +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: argocd-commit-server-network-policy +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - protocol: TCP + port: 8086 + - from: + - namespaceSelector: { } + ports: + - port: 8087 diff --git a/manifests/base/commit-server/argocd-commit-server-sa.yaml b/manifests/base/commit-server/argocd-commit-server-sa.yaml new file mode 100644 index 0000000000000..802d484ed3ffe --- /dev/null +++ b/manifests/base/commit-server/argocd-commit-server-sa.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: commit-server + name: argocd-commit-server diff --git a/manifests/base/commit-server/argocd-commit-server-service.yaml b/manifests/base/commit-server/argocd-commit-server-service.yaml new file mode 100644 index 0000000000000..75e761a10e666 --- /dev/null +++ b/manifests/base/commit-server/argocd-commit-server-service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: commit-server + name: argocd-commit-server +spec: + ports: + - name: server + protocol: TCP + port: 8086 + targetPort: 8086 + - name: metrics + protocol: TCP + port: 8087 + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server diff --git a/manifests/base/commit-server/kustomization.yaml b/manifests/base/commit-server/kustomization.yaml new file mode 100644 index 0000000000000..1bdee4f2c1430 --- /dev/null +++ b/manifests/base/commit-server/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- argocd-commit-server-sa.yaml +- argocd-commit-server-deployment.yaml +- argocd-commit-server-service.yaml +- argocd-commit-server-network-policy.yaml diff --git a/manifests/base/dex/argocd-dex-server-deployment.yaml b/manifests/base/dex/argocd-dex-server-deployment.yaml index f2d77c6ac1f6a..87d7d0a2fbbd8 100644 --- a/manifests/base/dex/argocd-dex-server-deployment.yaml +++ b/manifests/base/dex/argocd-dex-server-deployment.yaml @@ -104,3 +104,5 @@ spec: matchLabels: app.kubernetes.io/part-of: argocd topologyKey: kubernetes.io/hostname + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/notification/argocd-notifications-controller-deployment.yaml b/manifests/base/notification/argocd-notifications-controller-deployment.yaml index b13acf718f93c..c3a533e5a4350 100644 --- a/manifests/base/notification/argocd-notifications-controller-deployment.yaml +++ b/manifests/base/notification/argocd-notifications-controller-deployment.yaml @@ -89,3 +89,5 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/redis/argocd-redis-deployment.yaml b/manifests/base/redis/argocd-redis-deployment.yaml index c591db0d0aa4a..cbfebb8a2127c 100644 --- a/manifests/base/redis/argocd-redis-deployment.yaml +++ b/manifests/base/redis/argocd-redis-deployment.yaml @@ -77,3 +77,5 @@ spec: matchLabels: app.kubernetes.io/part-of: argocd topologyKey: kubernetes.io/hostname + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index 0e86acd3e3b5e..02a11fabe9715 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -149,6 +149,12 @@ spec: name: argocd-cmd-params-cm key: reposerver.plugin.tar.exclusions optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -330,3 +336,5 @@ spec: matchLabels: app.kubernetes.io/part-of: argocd topologyKey: kubernetes.io/hostname + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index 56b479fdcfd44..5b0d688e80ad6 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -292,6 +292,12 @@ spec: name: argocd-cmd-params-cm key: applicationsetcontroller.enable.scm.providers optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: hydrator.enabled + optional: true volumeMounts: - name: ssh-known-hosts mountPath: /app/config/ssh @@ -385,3 +391,5 @@ spec: matchLabels: app.kubernetes.io/part-of: argocd topologyKey: kubernetes.io/hostname + nodeSelector: + kubernetes.io/os: linux \ No newline at end of file diff --git a/manifests/cluster-install-with-hydrator/kustomization.yaml b/manifests/cluster-install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..f813a3105aa6c --- /dev/null +++ b/manifests/cluster-install-with-hydrator/kustomization.yaml @@ -0,0 +1,12 @@ +resources: + - ../cluster-install + - ../base/commit-server + +patches: + - target: + kind: ConfigMap + name: argocd-cmd-params-cm + patch: |- + - op: add + path: /data + value: {"hydrator.enabled": "true"} diff --git a/manifests/core-install-with-hydrator.yaml b/manifests/core-install-with-hydrator.yaml new file mode 100644 index 0000000000000..80ec8a154c49b --- /dev/null +++ b/manifests/core-install-with-hydrator.yaml @@ -0,0 +1,25227 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + - jsonPath: .spec.project + name: Project + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to + apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: |- + Project is a reference to the project this application belongs to. + The empty string means that application belongs to the 'default' project. + type: string + revisionHistoryLimit: + description: |- + RevisionHistoryLimit limits the number of items kept in the application's revision history, which is used for informational purposes as well as for rollbacks to previous versions. + This should only be changed in exceptional circumstances. + Setting to zero will store no history. This will reduce storage used. + Increasing will increase the space used to store the history, so we do not recommend increasing it. + Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether to + apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize adds + to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifies whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usually an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string + health: + description: Health contains information about the application's current + health status + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: |- + ObservedAt indicates when the application state was updated without querying latest git state + Deprecated: controller no longer updates ObservedAt field + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over + Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors + or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block. ValuesObject takes precedence + over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies + whether to apply common labels to resource + selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize + Replicas override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + managedNamespaceMetadata: + description: ManagedNamespaceMetadata contains the current + sync state of managed namespace metadata + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: |- + HookPhase contains the state of any operation associated with this resource OR hook + This can also contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name. This must be set + if Server is not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyNestedSelectors: + type: boolean + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + goTemplate: + type: boolean + goTemplateOptions: + items: + type: string + type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array + preservedFields: + properties: + annotations: + items: + type: string + type: array + labels: + items: + type: string + type: array + type: object + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + templatePatch: + type: string + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + targetRevisions: + items: + type: string + type: array + required: + - application + - message + - status + - step + - targetRevisions + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + resources: + items: + properties: + group: + type: string + health: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AppProject provides a logical grouping of applications, providing controls for: + * where the apps may deploy to (cluster whitelist) + * what may be deployed (repository whitelist, resource whitelist/blacklist) + * who can access these applications (roles, OIDC group claims bindings) + * and what they can do (RBAC policies) + * automation access to these roles (JWT tokens) + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: DefaultServiceAccount to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + required: + - defaultServiceAccount + - server + type: object + type: array + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller + namespace: argocd +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cm + app.kubernetes.io/part-of: argocd + name: argocd-cm +--- +apiVersion: v1 +data: + hydrator.enabled: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cmd-params-cm + app.kubernetes.io/part-of: argocd + name: argocd-cmd-params-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-gpg-keys-cm + app.kubernetes.io/part-of: argocd + name: argocd-gpg-keys-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-rbac-cm + app.kubernetes.io/part-of: argocd + name: argocd-rbac-cm +--- +apiVersion: v1 +data: + ssh_known_hosts: | + # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT + [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE= + bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-ssh-known-hosts-cm + app.kubernetes.io/part-of: argocd + name: argocd-ssh-known-hosts-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-tls-certs-cm + app.kubernetes.io/part-of: argocd + name: argocd-tls-certs-cm +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: argocd-secret + app.kubernetes.io/part-of: argocd + name: argocd-secret +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + ports: + - name: webhook + port: 7000 + protocol: TCP + targetPort: webhook + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + ports: + - name: server + port: 8086 + protocol: TCP + targetPort: 8086 + - name: metrics + port: 8087 + protocol: TCP + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/name: argocd-metrics + app.kubernetes.io/part-of: argocd + name: argocd-metrics +spec: + ports: + - name: metrics + port: 8082 + protocol: TCP + targetPort: 8082 + selector: + app.kubernetes.io/name: argocd-application-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + ports: + - name: tcp-redis + port: 6379 + targetPort: 6379 + selector: + app.kubernetes.io/name: argocd-redis +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + ports: + - name: server + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 8084 + protocol: TCP + targetPort: 8084 + selector: + app.kubernetes.io/name: argocd-repo-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-applicationset-controller + env: + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.annotations + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.labels + name: argocd-cmd-params-cm + optional: true + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.policy.override + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_CONCURRENT_RECONCILIATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.concurrent.reconciliations.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-applicationset-controller + ports: + - containerPort: 7000 + name: webhook + - containerPort: 8080 + name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-applicationset-controller + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: commitserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: commitserver.log.level + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-commit-server + ports: + - containerPort: 8086 + - containerPort: 8087 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + serviceAccountName: argocd-commit-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-commit-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis + template: + metadata: + labels: + app.kubernetes.io/name: argocd-redis + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - --save + - "" + - --appendonly + - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine + imagePullPolicy: Always + name: redis + ports: + - containerPort: 6379 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-redis +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-repo-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-repo-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: reposerver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: reposerver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_METRICS_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: reposerver.disable.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: reposerver.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.repo.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.max.combined.directory.manifests.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.tar.exclusions + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.disable.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.revision.cache.lock.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GRPC_MAX_SIZE_MB + valueFrom: + configMapKeyRef: + key: reposerver.grpc.max.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES + valueFrom: + configMapKeyRef: + key: reposerver.include.hidden.directories + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8084 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-repo-server + ports: + - containerPort: 8081 + - containerPort: 8084 + readinessProbe: + httpGet: + path: /healthz + port: 8084 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /tmp + name: tmp + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-repo-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - emptyDir: {} + name: helm-working-dir + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - emptyDir: {} + name: var-files + - emptyDir: {} + name: plugins +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + serviceName: argocd-application-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-application-controller + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-application-controller + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_CONTROLLER_REPLICAS + value: "1" + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.hard.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.status.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.operation.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: controller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: controller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.metrics.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: controller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: controller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + key: controller.resource.health.persist + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM + valueFrom: + configMapKeyRef: + key: controller.sharding.algorithm + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: controller.kubectl.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.ignore.normalizer.jq.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-application-controller + ports: + - containerPort: 8082 + readinessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp + workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-application-controller + volumes: + - emptyDir: {} + name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-application-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8082 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-applicationset-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 7000 + protocol: TCP + - port: 8080 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-commit-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 8086 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8087 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 6379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-repo-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + ports: + - port: 8081 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8084 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + policyTypes: + - Ingress diff --git a/manifests/core-install-with-hydrator/kustomization.yaml b/manifests/core-install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..280fd775877c2 --- /dev/null +++ b/manifests/core-install-with-hydrator/kustomization.yaml @@ -0,0 +1,12 @@ +resources: + - ../core-install + - ../base/commit-server + +patches: + - target: + kind: ConfigMap + name: argocd-cmd-params-cm + patch: |- + - op: add + path: /data + value: {"hydrator.enabled": "true"} diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index f558902d4692d..1958f6fc18cd1 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -115,6 +115,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -304,6 +309,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -451,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -670,6 +687,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -819,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1151,6 +1180,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1297,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1363,6 +1404,64 @@ spec: required: - repoURL type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: description: Sources is a reference to the location of the application's manifests or chart @@ -1508,6 +1607,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1655,6 +1762,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1833,6 +1944,11 @@ spec: description: Health contains information about the application's current health status properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -2030,6 +2146,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2179,6 +2303,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2399,6 +2527,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2550,6 +2686,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2710,6 +2850,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2913,6 +3058,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3065,6 +3218,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3300,6 +3458,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3455,6 +3621,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -3804,6 +3975,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3955,6 +4134,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4185,6 +4368,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4337,6 +4528,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4443,6 +4638,11 @@ spec: description: HealthStatus contains information about the currently observed health state of an application or resource properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -4460,6 +4660,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4473,6 +4675,177 @@ spec: type: string type: object type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object sourceType: description: SourceType specifies the type of this application type: string @@ -4710,6 +5083,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4861,6 +5242,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5091,6 +5476,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -5243,6 +5636,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5579,6 +5976,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5677,6 +6078,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5722,6 +6125,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -5809,6 +6248,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5907,6 +6350,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6013,6 +6458,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6648,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6299,6 +6750,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6344,6 +6797,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -6431,6 +6920,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6529,6 +7022,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6824,6 +7319,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6922,6 +7421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6967,6 +7468,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -7054,6 +7591,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7152,6 +7693,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7427,6 +7970,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7525,6 +8072,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7570,14 +8119,50 @@ spec: required: - repoURL type: object - sources: - items: - properties: - chart: - type: string - directory: - properties: - exclude: + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: type: string include: type: string @@ -7657,6 +8242,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7755,6 +8344,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8055,6 +8646,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8153,6 +8748,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8198,6 +8795,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8285,6 +8918,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8383,6 +9020,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8489,6 +9128,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +9318,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8775,6 +9420,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8820,6 +9467,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8907,6 +9590,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9005,6 +9692,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9300,6 +9989,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9398,6 +10091,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9443,6 +10138,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -9530,6 +10261,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9628,6 +10363,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9903,6 +10640,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10001,6 +10742,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10046,6 +10789,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10133,6 +10912,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10231,6 +11014,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10514,6 +11299,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10612,6 +11401,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10657,6 +11448,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10744,6 +11571,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10842,6 +11673,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11344,6 +12177,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11442,6 +12279,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11487,6 +12326,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -11574,6 +12449,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11672,6 +12551,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12169,6 +13050,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12267,6 +13152,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12312,6 +13199,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -12399,6 +13322,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12497,6 +13424,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12789,6 +13718,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12887,6 +13820,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12932,6 +13867,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13019,6 +13990,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13117,6 +14092,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13419,6 +14396,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13517,6 +14498,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13562,6 +14545,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13649,6 +14668,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13747,6 +14770,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13853,6 +14878,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +15068,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14139,6 +15170,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14184,6 +15217,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14271,6 +15340,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14369,6 +15442,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14664,6 +15739,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14762,6 +15841,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14807,6 +15888,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14894,6 +16011,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14992,6 +16113,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15267,6 +16390,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15365,6 +16492,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15410,6 +16539,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -15497,6 +16662,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15595,6 +16764,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15878,6 +17049,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15976,6 +17151,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16012,14 +17189,50 @@ spec: type: object type: array type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object required: - - repoURL + - drySource + - syncSource type: object sources: items: @@ -16108,6 +17321,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16206,6 +17423,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16708,6 +17927,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16806,6 +18029,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16851,6 +18076,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -16938,6 +18199,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17036,6 +18301,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17533,6 +18800,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17631,6 +18902,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17676,6 +18949,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -17763,6 +19072,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17861,6 +19174,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18157,6 +19472,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18255,6 +19574,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18300,6 +19621,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18387,6 +19744,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18485,6 +19846,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18767,6 +20130,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18865,6 +20232,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18910,6 +20279,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18997,6 +20402,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19095,6 +20504,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19597,6 +21008,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19695,6 +21110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19740,6 +21157,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -19827,6 +21280,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19925,6 +21382,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20422,6 +21881,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20520,6 +21983,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20565,6 +22030,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -20652,6 +22153,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20750,6 +22255,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21117,6 +22624,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21215,6 +22726,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21260,6 +22773,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -21347,6 +22896,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21445,6 +22998,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21604,6 +23159,9 @@ spec: type: string health: properties: + lastTransitionTime: + format: date-time + type: string message: type: string status: @@ -21617,6 +23175,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +23295,7 @@ spec: sync operation. properties: defaultServiceAccount: - description: ServiceAccountName to be used for impersonation + description: DefaultServiceAccount to be used for impersonation during the sync operation type: string namespace: @@ -21746,6 +23306,9 @@ spec: description: Server specifies the URL of the target cluster's Kubernetes control plane API. type: string + required: + - defaultServiceAccount + - server type: object type: array destinations: @@ -22498,6 +24061,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -22558,6 +24127,12 @@ spec: key: applicationsetcontroller.webhook.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -22588,6 +24163,8 @@ spec: name: tmp - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-applicationset-controller volumes: - configMap: @@ -22688,6 +24265,8 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 999 @@ -22857,6 +24436,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -22995,6 +24580,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -23145,6 +24732,30 @@ spec: key: controller.self.heal.timeout.seconds name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -23253,6 +24864,14 @@ spec: key: controller.ignore.normalizer.jq.timeout name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -23280,11 +24899,17 @@ spec: name: argocd-home - mountPath: /home/argocd/params name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-application-controller volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: items: diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 5878e6eacd6a7..e2dac9a68be74 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -114,6 +114,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -303,6 +308,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -450,6 +463,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -669,6 +686,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -818,6 +843,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1150,6 +1179,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1296,6 +1333,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1362,6 +1403,64 @@ spec: required: - repoURL type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: description: Sources is a reference to the location of the application's manifests or chart @@ -1507,6 +1606,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1654,6 +1761,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1832,6 +1943,11 @@ spec: description: Health contains information about the application's current health status properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -2029,6 +2145,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2178,6 +2302,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2398,6 +2526,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2549,6 +2685,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2709,6 +2849,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2912,6 +3057,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3064,6 +3217,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3299,6 +3457,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3454,6 +3620,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -3803,6 +3974,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3954,6 +4133,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4184,6 +4367,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4336,6 +4527,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4442,6 +4637,11 @@ spec: description: HealthStatus contains information about the currently observed health state of an application or resource properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -4459,6 +4659,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4472,6 +4674,177 @@ spec: type: string type: object type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object sourceType: description: SourceType specifies the type of this application type: string @@ -4709,6 +5082,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4860,6 +5241,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5090,6 +5475,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -5242,6 +5635,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index ddfa9b27be056..97b4cf0339daf 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -231,6 +231,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -329,6 +333,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -374,6 +380,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -461,6 +503,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -559,6 +605,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -665,6 +713,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -853,6 +903,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -951,6 +1005,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -996,6 +1052,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -1083,6 +1175,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1181,6 +1277,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -1476,6 +1574,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1574,6 +1676,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -1619,6 +1723,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -1706,6 +1846,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1804,6 +1948,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2079,6 +2225,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2177,6 +2327,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2222,6 +2374,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -2309,6 +2497,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2407,6 +2599,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2707,6 +2901,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2805,6 +3003,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2850,6 +3050,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -2937,6 +3173,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3035,6 +3275,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3141,6 +3383,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -3329,6 +3573,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3427,6 +3675,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3472,6 +3722,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -3559,6 +3845,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3657,6 +3947,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3952,6 +4244,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4050,6 +4346,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4095,6 +4393,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -4182,6 +4516,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4280,6 +4618,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4555,6 +4895,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4653,6 +4997,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4698,6 +5044,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -4785,6 +5167,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4883,6 +5269,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5166,6 +5554,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5264,6 +5656,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5309,6 +5703,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -5396,6 +5826,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5494,6 +5928,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5996,6 +6432,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6094,6 +6534,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6139,6 +6581,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -6226,6 +6704,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6324,6 +6806,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6821,6 +7305,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6919,6 +7407,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6964,6 +7454,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -7051,6 +7577,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7149,6 +7679,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7441,6 +7973,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7539,6 +8075,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7584,6 +8122,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -7671,6 +8245,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7769,6 +8347,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8071,6 +8651,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8169,6 +8753,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8214,6 +8800,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8301,6 +8923,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8399,6 +9025,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8505,6 +9133,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8693,6 +9323,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8791,6 +9425,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8836,6 +9472,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8923,6 +9595,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9021,6 +9697,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9316,6 +9994,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9414,6 +10096,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9459,6 +10143,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -9546,6 +10266,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9644,6 +10368,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9919,6 +10645,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10017,6 +10747,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10062,6 +10794,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10149,6 +10917,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10247,6 +11019,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10530,6 +11304,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10628,6 +11406,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10673,6 +11453,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10760,6 +11576,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10858,6 +11678,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11360,6 +12182,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11458,6 +12284,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11503,6 +12331,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -11590,6 +12454,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11688,6 +12556,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12185,6 +13055,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12283,6 +13157,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12328,6 +13204,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -12415,6 +13327,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12513,6 +13429,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12809,6 +13727,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12907,6 +13829,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12952,6 +13876,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13039,6 +13999,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13137,6 +14101,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13419,6 +14385,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13517,6 +14487,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13562,6 +14534,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13649,6 +14657,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13747,6 +14759,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14249,6 +15263,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14347,6 +15365,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14392,6 +15412,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14479,6 +15535,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14577,6 +15637,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15074,6 +16136,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15172,6 +16238,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15217,6 +16285,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -15304,6 +16408,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15402,6 +16510,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15769,6 +16879,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15867,6 +16981,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15912,6 +17028,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -15999,6 +17151,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16097,6 +17253,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16256,6 +17414,9 @@ spec: type: string health: properties: + lastTransitionTime: + format: date-time + type: string message: type: string status: @@ -16269,6 +17430,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: diff --git a/manifests/crds/appproject-crd.yaml b/manifests/crds/appproject-crd.yaml index 07e98e13b5928..a72a8de146939 100644 --- a/manifests/crds/appproject-crd.yaml +++ b/manifests/crds/appproject-crd.yaml @@ -95,7 +95,7 @@ spec: sync operation. properties: defaultServiceAccount: - description: ServiceAccountName to be used for impersonation + description: DefaultServiceAccount to be used for impersonation during the sync operation type: string namespace: @@ -106,6 +106,9 @@ spec: description: Server specifies the URL of the target cluster's Kubernetes control plane API. type: string + required: + - defaultServiceAccount + - server type: object type: array destinations: diff --git a/manifests/ha/base/redis-ha/chart/upstream.yaml b/manifests/ha/base/redis-ha/chart/upstream.yaml index a9963b70cce1d..79e356f983762 100644 --- a/manifests/ha/base/redis-ha/chart/upstream.yaml +++ b/manifests/ha/base/redis-ha/chart/upstream.yaml @@ -1375,7 +1375,12 @@ spec: - mountPath: /health name: health lifecycle: - {} + postStart: + exec: + command: + - /bin/sh + - -c + - sleep 30; redis-cli -p 26379 sentinel reset argocd - name: split-brain-fix image: public.ecr.aws/docker/library/redis:7.0.15-alpine diff --git a/manifests/ha/base/redis-ha/chart/values.yaml b/manifests/ha/base/redis-ha/chart/values.yaml index fdf1846bcef5b..47e0910c1ae41 100644 --- a/manifests/ha/base/redis-ha/chart/values.yaml +++ b/manifests/ha/base/redis-ha/chart/values.yaml @@ -7,8 +7,8 @@ redis-ha: redis: masterGroupName: argocd config: - save: "\"\"" - bind: "0.0.0.0" + save: '""' + bind: '0.0.0.0' haproxy: enabled: true IPv6: @@ -26,4 +26,11 @@ redis-ha: tag: 7.0.15-alpine containerSecurityContext: null sentinel: - bind: "0.0.0.0" + bind: '0.0.0.0' + lifecycle: + postStart: + exec: + command: + - '/bin/sh' + - '-c' + - 'sleep 30; redis-cli -p 26379 sentinel reset argocd' diff --git a/manifests/ha/cluster-install-with-hydrator/kustomization.yaml b/manifests/ha/cluster-install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..da24e1594336a --- /dev/null +++ b/manifests/ha/cluster-install-with-hydrator/kustomization.yaml @@ -0,0 +1,3 @@ +resources: + - ../cluster-install + - ../../base/commit-server diff --git a/manifests/ha/install-with-hydrator.yaml b/manifests/ha/install-with-hydrator.yaml new file mode 100644 index 0000000000000..5f3dda5c00ad6 --- /dev/null +++ b/manifests/ha/install-with-hydrator.yaml @@ -0,0 +1,27558 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + - jsonPath: .spec.project + name: Project + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to + apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: |- + Project is a reference to the project this application belongs to. + The empty string means that application belongs to the 'default' project. + type: string + revisionHistoryLimit: + description: |- + RevisionHistoryLimit limits the number of items kept in the application's revision history, which is used for informational purposes as well as for rollbacks to previous versions. + This should only be changed in exceptional circumstances. + Setting to zero will store no history. This will reduce storage used. + Increasing will increase the space used to store the history, so we do not recommend increasing it. + Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether to + apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize adds + to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifies whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usually an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string + health: + description: Health contains information about the application's current + health status + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: |- + ObservedAt indicates when the application state was updated without querying latest git state + Deprecated: controller no longer updates ObservedAt field + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over + Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors + or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block. ValuesObject takes precedence + over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies + whether to apply common labels to resource + selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize + Replicas override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + managedNamespaceMetadata: + description: ManagedNamespaceMetadata contains the current + sync state of managed namespace metadata + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: |- + HookPhase contains the state of any operation associated with this resource OR hook + This can also contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name. This must be set + if Server is not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyNestedSelectors: + type: boolean + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + goTemplate: + type: boolean + goTemplateOptions: + items: + type: string + type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array + preservedFields: + properties: + annotations: + items: + type: string + type: array + labels: + items: + type: string + type: array + type: object + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + templatePatch: + type: string + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + targetRevisions: + items: + type: string + type: array + required: + - application + - message + - status + - step + - targetRevisions + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + resources: + items: + properties: + group: + type: string + health: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AppProject provides a logical grouping of applications, providing controls for: + * where the apps may deploy to (cluster whitelist) + * what may be deployed (repository whitelist, resource whitelist/blacklist) + * who can access these applications (roles, OIDC group claims bindings) + * and what they can do (RBAC policies) + * automation access to these roles (JWT tokens) + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: DefaultServiceAccount to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + required: + - defaultServiceAccount + - server + type: object + type: array + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +secrets: +- name: argocd-redis +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resourceNames: + - argocd-notifications-cm + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resourceNames: + - argocd-notifications-secret + resources: + - secrets + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +rules: +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - delete + - get + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - list +- apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create +- apiGroups: + - argoproj.io + resources: + - workflows + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-dex-server +subjects: +- kind: ServiceAccount + name: argocd-dex-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-notifications-controller +subjects: +- kind: ServiceAccount + name: argocd-notifications-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis-ha +subjects: +- kind: ServiceAccount + name: argocd-redis-ha +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis-ha-haproxy +subjects: +- kind: ServiceAccount + name: argocd-redis-ha-haproxy +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server + namespace: argocd +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cm + app.kubernetes.io/part-of: argocd + name: argocd-cm +--- +apiVersion: v1 +data: + redis.server: argocd-redis-ha-haproxy:6379 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cmd-params-cm + app.kubernetes.io/part-of: argocd + name: argocd-cmd-params-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-gpg-keys-cm + app.kubernetes.io/part-of: argocd + name: argocd-gpg-keys-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-rbac-cm + app.kubernetes.io/part-of: argocd + name: argocd-rbac-cm +--- +apiVersion: v1 +data: + fix-split-brain.sh: | + HOSTNAME="$(hostname)" + INDEX="${HOSTNAME##*-}" + SENTINEL_PORT=26379 + ANNOUNCE_IP='' + MASTER='' + MASTER_GROUP="argocd" + QUORUM="2" + REDIS_CONF=/data/conf/redis.conf + REDIS_PORT=6379 + REDIS_TLS_PORT= + SENTINEL_CONF=/data/conf/sentinel.conf + SENTINEL_TLS_PORT= + SERVICE=argocd-redis-ha + SENTINEL_TLS_REPLICATION_ENABLED=false + REDIS_TLS_REPLICATION_ENABLED=false + + ROLE='' + REDIS_MASTER='' + + set -eu + sentinel_get_master() { + set +e + if [ "$SENTINEL_PORT" -eq 0 ]; then + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + else + redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + fi + set -e + } + + sentinel_get_master_retry() { + master='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + master=$(sentinel_get_master) + if [ -n "${master}" ]; then + break + fi + sleep $((sleep + i)) + done + echo "${master}" + } + + identify_master() { + echo "Identifying redis master (get-master-addr-by-name).." + echo " using sentinel (argocd-redis-ha), sentinel group name (argocd)" + MASTER="$(sentinel_get_master_retry 3)" + if [ -n "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + else + echo " $(date) Did not find redis master (${MASTER})" + fi + } + + sentinel_update() { + echo "Updating sentinel config.." + echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})" + eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}" + echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})" + sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}" + if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then + echo " redis master (${1}:${REDIS_TLS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + else + echo " redis master (${1}:${REDIS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + fi + echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF} + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})" + echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF} + else + echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})" + echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF} + fi + } + + redis_update() { + echo "Updating redis config.." + if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then + echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})" + echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF} + else + echo " we are slave of redis master (${1}:${REDIS_PORT})" + echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF} + fi + echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF} + } + + copy_config() { + echo "Copying default redis config.." + echo " to '${REDIS_CONF}'" + cp /readonly-config/redis.conf "${REDIS_CONF}" + echo "Copying default sentinel config.." + echo " to '${SENTINEL_CONF}'" + cp /readonly-config/sentinel.conf "${SENTINEL_CONF}" + } + + setup_defaults() { + echo "Setting up defaults.." + echo " using statefulset index (${INDEX})" + if [ "${INDEX}" = "0" ]; then + echo "Setting this pod as master for redis and sentinel.." + echo " using announce (${ANNOUNCE_IP})" + redis_update "${ANNOUNCE_IP}" + sentinel_update "${ANNOUNCE_IP}" + echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)" + sed -i "s/^.*slaveof.*//" "${REDIS_CONF}" + else + echo "Getting redis master ip.." + echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master" + DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')" + if [ -z "${DEFAULT_MASTER}" ]; then + echo "Error: Unable to resolve redis master (getent hosts)." + exit 1 + fi + echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})" + echo "Setting default slave config for redis and sentinel.." + echo " using master ip (${DEFAULT_MASTER})" + redis_update "${DEFAULT_MASTER}" + sentinel_update "${DEFAULT_MASTER}" + fi + } + + redis_ping() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + else + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping + fi + set -e + } + + redis_ping_retry() { + ping='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + if [ "$(redis_ping)" = "PONG" ]; then + ping='PONG' + break + fi + sleep $((sleep + i)) + MASTER=$(sentinel_get_master) + done + echo "${ping}" + } + + find_master() { + echo "Verifying redis master.." + if [ "$REDIS_PORT" -eq 0 ]; then + echo " ping (${MASTER}:${REDIS_TLS_PORT})" + else + echo " ping (${MASTER}:${REDIS_PORT})" + fi + if [ "$(redis_ping_retry 3)" != "PONG" ]; then + echo " $(date) Can't ping redis master (${MASTER})" + echo "Attempting to force failover (sentinel failover).." + + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + else + echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + fi + + echo "Hold on for 10sec" + sleep 10 + echo "We should get redis master's ip now. Asking (get-master-addr-by-name).." + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + else + echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + fi + MASTER="$(sentinel_get_master)" + if [ "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + else + echo "$(date) Error: Could not failover, exiting..." + exit 1 + fi + else + echo " $(date) Found reachable redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + fi + } + + redis_ro_update() { + echo "Updating read-only redis config.." + echo " redis.conf set 'replica-priority 0'" + echo "replica-priority 0" >> ${REDIS_CONF} + } + + getent_hosts() { + index=${1:-${INDEX}} + service="${SERVICE}-announce-${index}" + host=$(getent hosts "${service}") + echo "${host}" + } + + identify_announce_ip() { + echo "Identify announce ip for this pod.." + echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})" + ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }') + echo " identified announce (${ANNOUNCE_IP})" + } + + redis_role() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + else + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + fi + set -e + } + + identify_redis_master() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + else + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + fi + set -e + } + + reinit() { + set +e + sh /readonly-config/init.sh + + if [ "$REDIS_PORT" -eq 0 ]; then + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + else + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" + fi + set -e + } + + identify_announce_ip + + while [ -z "${ANNOUNCE_IP}" ]; do + echo "Error: Could not resolve the announce ip for this pod." + sleep 30 + identify_announce_ip + done + + trap "exit 0" TERM + while true; do + sleep 60 + + # where is redis master + identify_master + + if [ "$MASTER" = "$ANNOUNCE_IP" ]; then + redis_role + if [ "$ROLE" != "master" ]; then + reinit + fi + elif [ "${MASTER}" ]; then + identify_redis_master + if [ "$REDIS_MASTER" != "$MASTER" ]; then + reinit + fi + fi + done + haproxy.cfg: "defaults REDIS\n mode tcp\n timeout connect 4s\n timeout server + 6m\n timeout client 6m\n timeout check 2s\n\nlisten health_check_http_url\n + \ bind :8888 \n mode http\n monitor-uri /healthz\n option dontlognull\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_0\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE0\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_1\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE1\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_2\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE2\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n\n# + decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n + \ use_backend bk_redis_master\n# Check all redis servers to see if they think + they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 + check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) + ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise + 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge + 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend + stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" + haproxy_init.sh: | + HAPROXY_CONF=/data/haproxy.cfg + cp /readonly/haproxy.cfg "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-0 && break + echo "Waiting for service argocd-redis-ha-announce-0 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP0=$(getent hosts "argocd-redis-ha-announce-0" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP0" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-0" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE0/$ANNOUNCE_IP0/" "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-1 && break + echo "Waiting for service argocd-redis-ha-announce-1 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP1=$(getent hosts "argocd-redis-ha-announce-1" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP1" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-1" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE1/$ANNOUNCE_IP1/" "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-2 && break + echo "Waiting for service argocd-redis-ha-announce-2 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP2=$(getent hosts "argocd-redis-ha-announce-2" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP2" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-2" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE2/$ANNOUNCE_IP2/" "$HAPROXY_CONF" + init.sh: | + echo "$(date) Start..." + HOSTNAME="$(hostname)" + INDEX="${HOSTNAME##*-}" + SENTINEL_PORT=26379 + ANNOUNCE_IP='' + MASTER='' + MASTER_GROUP="argocd" + QUORUM="2" + REDIS_CONF=/data/conf/redis.conf + REDIS_PORT=6379 + REDIS_TLS_PORT= + SENTINEL_CONF=/data/conf/sentinel.conf + SENTINEL_TLS_PORT= + SERVICE=argocd-redis-ha + SENTINEL_TLS_REPLICATION_ENABLED=false + REDIS_TLS_REPLICATION_ENABLED=false + + set -eu + sentinel_get_master() { + set +e + if [ "$SENTINEL_PORT" -eq 0 ]; then + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + else + redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + fi + set -e + } + + sentinel_get_master_retry() { + master='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + master=$(sentinel_get_master) + if [ -n "${master}" ]; then + break + fi + sleep $((sleep + i)) + done + echo "${master}" + } + + identify_master() { + echo "Identifying redis master (get-master-addr-by-name).." + echo " using sentinel (argocd-redis-ha), sentinel group name (argocd)" + MASTER="$(sentinel_get_master_retry 3)" + if [ -n "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + else + echo " $(date) Did not find redis master (${MASTER})" + fi + } + + sentinel_update() { + echo "Updating sentinel config.." + echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})" + eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}" + echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})" + sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}" + if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then + echo " redis master (${1}:${REDIS_TLS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + else + echo " redis master (${1}:${REDIS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + fi + echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF} + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})" + echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF} + else + echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})" + echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF} + fi + } + + redis_update() { + echo "Updating redis config.." + if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then + echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})" + echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF} + else + echo " we are slave of redis master (${1}:${REDIS_PORT})" + echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF} + fi + echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF} + } + + copy_config() { + echo "Copying default redis config.." + echo " to '${REDIS_CONF}'" + cp /readonly-config/redis.conf "${REDIS_CONF}" + echo "Copying default sentinel config.." + echo " to '${SENTINEL_CONF}'" + cp /readonly-config/sentinel.conf "${SENTINEL_CONF}" + } + + setup_defaults() { + echo "Setting up defaults.." + echo " using statefulset index (${INDEX})" + if [ "${INDEX}" = "0" ]; then + echo "Setting this pod as master for redis and sentinel.." + echo " using announce (${ANNOUNCE_IP})" + redis_update "${ANNOUNCE_IP}" + sentinel_update "${ANNOUNCE_IP}" + echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)" + sed -i "s/^.*slaveof.*//" "${REDIS_CONF}" + else + echo "Getting redis master ip.." + echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master" + DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')" + if [ -z "${DEFAULT_MASTER}" ]; then + echo "Error: Unable to resolve redis master (getent hosts)." + exit 1 + fi + echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})" + echo "Setting default slave config for redis and sentinel.." + echo " using master ip (${DEFAULT_MASTER})" + redis_update "${DEFAULT_MASTER}" + sentinel_update "${DEFAULT_MASTER}" + fi + } + + redis_ping() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + else + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping + fi + set -e + } + + redis_ping_retry() { + ping='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + if [ "$(redis_ping)" = "PONG" ]; then + ping='PONG' + break + fi + sleep $((sleep + i)) + MASTER=$(sentinel_get_master) + done + echo "${ping}" + } + + find_master() { + echo "Verifying redis master.." + if [ "$REDIS_PORT" -eq 0 ]; then + echo " ping (${MASTER}:${REDIS_TLS_PORT})" + else + echo " ping (${MASTER}:${REDIS_PORT})" + fi + if [ "$(redis_ping_retry 3)" != "PONG" ]; then + echo " $(date) Can't ping redis master (${MASTER})" + echo "Attempting to force failover (sentinel failover).." + + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + else + echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + fi + + echo "Hold on for 10sec" + sleep 10 + echo "We should get redis master's ip now. Asking (get-master-addr-by-name).." + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + else + echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + fi + MASTER="$(sentinel_get_master)" + if [ "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + else + echo "$(date) Error: Could not failover, exiting..." + exit 1 + fi + else + echo " $(date) Found reachable redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + fi + } + + redis_ro_update() { + echo "Updating read-only redis config.." + echo " redis.conf set 'replica-priority 0'" + echo "replica-priority 0" >> ${REDIS_CONF} + } + + getent_hosts() { + index=${1:-${INDEX}} + service="${SERVICE}-announce-${index}" + host=$(getent hosts "${service}") + echo "${host}" + } + + identify_announce_ip() { + echo "Identify announce ip for this pod.." + echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})" + ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }') + echo " identified announce (${ANNOUNCE_IP})" + } + + mkdir -p /data/conf/ + + echo "Initializing config.." + copy_config + + # where is redis master + identify_master + + identify_announce_ip + + if [ -z "${ANNOUNCE_IP}" ]; then + "Error: Could not resolve the announce ip for this pod." + exit 1 + elif [ "${MASTER}" ]; then + find_master + else + setup_defaults + fi + + if [ "${AUTH:-}" ]; then + echo "Setting redis auth values.." + ESCAPED_AUTH=$(echo "${AUTH}" | sed -e 's/[\/&]/\\&/g'); + sed -i "s/replace-default-auth/${ESCAPED_AUTH}/" "${REDIS_CONF}" "${SENTINEL_CONF}" + fi + + if [ "${SENTINELAUTH:-}" ]; then + echo "Setting sentinel auth values" + ESCAPED_AUTH_SENTINEL=$(echo "$SENTINELAUTH" | sed -e 's/[\/&]/\\&/g'); + sed -i "s/replace-default-sentinel-auth/${ESCAPED_AUTH_SENTINEL}/" "$SENTINEL_CONF" + fi + + echo "$(date) Ready..." + redis.conf: | + dir "/data" + port 6379 + rename-command FLUSHDB "" + rename-command FLUSHALL "" + bind 0.0.0.0 + maxmemory 0 + maxmemory-policy volatile-lru + min-replicas-max-lag 5 + min-replicas-to-write 1 + rdbchecksum yes + rdbcompression yes + repl-diskless-sync yes + save "" + requirepass replace-default-auth + masterauth replace-default-auth + sentinel.conf: | + dir "/data" + port 26379 + bind 0.0.0.0 + sentinel down-after-milliseconds argocd 10000 + sentinel failover-timeout argocd 180000 + maxclients 10000 + sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth + trigger-failover-if-master.sh: | + get_redis_role() { + is_master=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + info | grep -c 'role:master' || true + ) + } + get_redis_role + if [[ "$is_master" -eq 1 ]]; then + echo "This node is currently master, we trigger a failover." + response=$( + redis-cli \ + -h localhost \ + -p 26379 \ + SENTINEL failover argocd + ) + if [[ "$response" != "OK" ]] ; then + echo "$response" + exit 1 + fi + timeout=30 + while [[ "$is_master" -eq 1 && $timeout -gt 0 ]]; do + sleep 1 + get_redis_role + timeout=$((timeout - 1)) + done + echo "Failover successful" + fi +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-configmap +--- +apiVersion: v1 +data: + redis_liveness.sh: | + response=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + ping + ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi + echo "response=$response" + redis_readiness.sh: | + response=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + ping + ) + if [ "$response" != "PONG" ] ; then + echo "$response" + exit 1 + fi + echo "response=$response" + sentinel_liveness.sh: | + response=$( + redis-cli \ + -h localhost \ + -p 26379 \ + ping + ) + if [ "$response" != "PONG" ]; then + echo "$response" + exit 1 + fi + echo "response=$response" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-health-configmap +--- +apiVersion: v1 +data: + ssh_known_hosts: | + # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT + [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE= + bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-ssh-known-hosts-cm + app.kubernetes.io/part-of: argocd + name: argocd-ssh-known-hosts-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-tls-certs-cm + app.kubernetes.io/part-of: argocd + name: argocd-tls-certs-cm +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-secret +type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: argocd-secret + app.kubernetes.io/part-of: argocd + name: argocd-secret +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + ports: + - name: webhook + port: 7000 + protocol: TCP + targetPort: webhook + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + ports: + - name: server + port: 8086 + protocol: TCP + targetPort: 8086 + - name: metrics + port: 8087 + protocol: TCP + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + ports: + - appProtocol: TCP + name: http + port: 5556 + protocol: TCP + targetPort: 5556 + - name: grpc + port: 5557 + protocol: TCP + targetPort: 5557 + - name: metrics + port: 5558 + protocol: TCP + targetPort: 5558 + selector: + app.kubernetes.io/name: argocd-dex-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/name: argocd-metrics + app.kubernetes.io/part-of: argocd + name: argocd-metrics +spec: + ports: + - name: metrics + port: 8082 + protocol: TCP + targetPort: 8082 + selector: + app.kubernetes.io/name: argocd-application-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller-metrics + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-metrics +spec: + ports: + - name: metrics + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/name: argocd-notifications-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +spec: + clusterIP: None + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + selector: + app.kubernetes.io/name: argocd-redis-ha + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-0 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-0 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-1 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-1 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-2 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-2 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +spec: + ports: + - name: tcp-haproxy + port: 6379 + protocol: TCP + targetPort: redis + - name: http-exporter-port + port: 9101 + protocol: TCP + targetPort: metrics-port + selector: + app.kubernetes.io/name: argocd-redis-ha-haproxy + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + ports: + - name: server + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 8084 + protocol: TCP + targetPort: 8084 + selector: + app.kubernetes.io/name: argocd-repo-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + - name: https + port: 443 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server-metrics + app.kubernetes.io/part-of: argocd + name: argocd-server-metrics +spec: + ports: + - name: metrics + port: 8083 + protocol: TCP + targetPort: 8083 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-applicationset-controller + env: + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.annotations + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.labels + name: argocd-cmd-params-cm + optional: true + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.policy.override + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_CONCURRENT_RECONCILIATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.concurrent.reconciliations.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-applicationset-controller + ports: + - containerPort: 7000 + name: webhook + - containerPort: 8080 + name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-applicationset-controller + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: commitserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: commitserver.log.level + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-commit-server + ports: + - containerPort: 8086 + - containerPort: 8087 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + serviceAccountName: argocd-commit-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-commit-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-dex-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - command: + - /shared/argocd-dex + - rundex + env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: dexserver.disable.tls + name: argocd-cmd-params-cm + optional: true + image: ghcr.io/dexidp/dex:v2.41.1 + imagePullPolicy: Always + name: dex + ports: + - containerPort: 5556 + - containerPort: 5557 + - containerPort: 5558 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + - mountPath: /tls + name: argocd-dex-server-tls + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /shared/argocd-dex + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-dex-server + volumes: + - emptyDir: {} + name: static-files + - emptyDir: {} + name: dexconfig + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: argocd-notifications-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-notifications + env: + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + tcpSocket: + port: 9001 + name: argocd-notifications-controller + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + workingDir: /app + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-notifications-controller + volumes: + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +spec: + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + strategy: + type: RollingUpdate + template: + metadata: + annotations: + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 + prometheus.io/path: /metrics + prometheus.io/port: "9101" + prometheus.io/scrape: "true" + labels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + name: argocd-redis-ha-haproxy + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + topologyKey: kubernetes.io/hostname + containers: + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: 8888 + initialDelaySeconds: 5 + periodSeconds: 3 + name: haproxy + ports: + - containerPort: 6379 + name: redis + - containerPort: 9101 + name: metrics-port + readinessProbe: + httpGet: + path: /healthz + port: 8888 + initialDelaySeconds: 5 + periodSeconds: 3 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /usr/local/etc/haproxy + name: data + - mountPath: /run/haproxy + name: shared-socket + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + - args: + - /readonly/haproxy_init.sh + command: + - sh + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine + imagePullPolicy: IfNotPresent + name: config-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly + name: config-volume + readOnly: true + - mountPath: /data + name: data + securityContext: + fsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + serviceAccountName: argocd-redis-ha-haproxy + volumes: + - configMap: + name: argocd-redis-ha-configmap + name: config-volume + - emptyDir: {} + name: shared-socket + - emptyDir: {} + name: data +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-repo-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: kubernetes.io/hostname + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-repo-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: reposerver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: reposerver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_METRICS_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: reposerver.disable.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: reposerver.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.repo.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.max.combined.directory.manifests.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.tar.exclusions + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.disable.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.revision.cache.lock.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GRPC_MAX_SIZE_MB + valueFrom: + configMapKeyRef: + key: reposerver.grpc.max.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES + valueFrom: + configMapKeyRef: + key: reposerver.include.hidden.directories + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8084 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-repo-server + ports: + - containerPort: 8081 + - containerPort: 8084 + readinessProbe: + httpGet: + path: /healthz + port: 8084 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /tmp + name: tmp + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-repo-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - emptyDir: {} + name: helm-working-dir + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - emptyDir: {} + name: var-files + - emptyDir: {} + name: plugins +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: argocd-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: kubernetes.io/hostname + containers: + - args: + - /usr/local/bin/argocd-server + env: + - name: ARGOCD_API_SERVER_REPLICAS + value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + key: server.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + key: server.basehref + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + key: server.rootpath + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: server.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + key: server.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + key: server.dex.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + key: server.disable.auth + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + key: server.enable.gzip + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: server.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + key: server.x.frame.options + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + key: server.content.security.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.dex.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.dex.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: server.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.connection.status.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.oidc.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.login.attempts.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + key: server.staticassets + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + key: server.http.cookie.maxnumber + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + key: server.enable.proxy.extension + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-server + ports: + - containerPort: 8080 + - containerPort: 8083 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/server/tls + name: argocd-repo-server-tls + - mountPath: /app/config/dex/tls + name: argocd-dex-server-tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /tmp + name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-server + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + serviceName: argocd-application-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-application-controller + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-application-controller + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_CONTROLLER_REPLICAS + value: "1" + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.hard.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.status.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.operation.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: controller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: controller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.metrics.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: controller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: controller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + key: controller.resource.health.persist + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM + valueFrom: + configMapKeyRef: + key: controller.sharding.algorithm + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: controller.kubectl.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.ignore.normalizer.jq.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-application-controller + ports: + - containerPort: 8082 + readinessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp + workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-application-controller + volumes: + - emptyDir: {} + name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-server +spec: + podManagementPolicy: OrderedReady + replicas: 3 + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + serviceName: argocd-redis-ha + template: + metadata: + annotations: + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 + labels: + app.kubernetes.io/name: argocd-redis-ha + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + topologyKey: kubernetes.io/hostname + automountServiceAccountToken: false + containers: + - args: + - /data/conf/redis.conf + command: + - redis-server + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /bin/sh + - /readonly-config/trigger-failover-if-master.sh + livenessProbe: + exec: + command: + - sh + - -c + - /health/redis_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + name: redis + ports: + - containerPort: 6379 + name: redis + readinessProbe: + exec: + command: + - sh + - -c + - /health/redis_readiness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + - mountPath: /health + name: health + - args: + - /data/conf/sentinel.conf + command: + - redis-sentinel + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - sleep 30; redis-cli -p 26379 sentinel reset argocd + livenessProbe: + exec: + command: + - sh + - -c + - /health/sentinel_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + name: sentinel + ports: + - containerPort: 26379 + name: sentinel + readinessProbe: + exec: + command: + - sh + - -c + - /health/sentinel_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 3 + timeoutSeconds: 15 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + - mountPath: /health + name: health + - args: + - /readonly-config/fix-split-brain.sh + command: + - sh + env: + - name: SENTINEL_ID_0 + value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 + - name: SENTINEL_ID_1 + value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 + - name: SENTINEL_ID_2 + value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + name: split-brain-fix + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + initContainers: + - args: + - /readonly-config/init.sh + command: + - sh + env: + - name: SENTINEL_ID_0 + value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 + - name: SENTINEL_ID_1 + value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 + - name: SENTINEL_ID_2 + value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + name: config-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + securityContext: + fsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccountName: argocd-redis-ha + terminationGracePeriodSeconds: 60 + volumes: + - configMap: + name: argocd-redis-ha-configmap + name: config + - configMap: + defaultMode: 493 + name: argocd-redis-ha-health-configmap + name: health + - emptyDir: {} + name: data + updateStrategy: + type: RollingUpdate +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-application-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8082 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-applicationset-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 7000 + protocol: TCP + - port: 8080 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-commit-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 8086 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8087 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-dex-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + ports: + - port: 5556 + protocol: TCP + - port: 5557 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 5558 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 9001 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-ha-proxy-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-ha-server-network-policy +spec: + egress: + - ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + to: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-repo-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + ports: + - port: 8081 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8084 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-server-network-policy +spec: + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + policyTypes: + - Ingress diff --git a/manifests/ha/install-with-hydrator/kustomization.yaml b/manifests/ha/install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..4dc48949d4ab7 --- /dev/null +++ b/manifests/ha/install-with-hydrator/kustomization.yaml @@ -0,0 +1,3 @@ +resources: + - ../base + - ../../base/commit-server diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index ba37a63431b6b..f502d4349d24d 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -115,6 +115,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -304,6 +309,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -451,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -670,6 +687,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -819,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1151,6 +1180,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1297,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1363,6 +1404,64 @@ spec: required: - repoURL type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: description: Sources is a reference to the location of the application's manifests or chart @@ -1508,6 +1607,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1655,6 +1762,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1833,6 +1944,11 @@ spec: description: Health contains information about the application's current health status properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -2030,6 +2146,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2179,6 +2303,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2399,6 +2527,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2550,6 +2686,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2710,6 +2850,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2913,6 +3058,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3065,6 +3218,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3300,6 +3458,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3455,6 +3621,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -3804,6 +3975,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3955,6 +4134,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4185,6 +4368,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4337,6 +4528,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4443,6 +4638,11 @@ spec: description: HealthStatus contains information about the currently observed health state of an application or resource properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -4460,6 +4660,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4473,6 +4675,177 @@ spec: type: string type: object type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object sourceType: description: SourceType specifies the type of this application type: string @@ -4710,6 +5083,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4861,6 +5242,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5091,6 +5476,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -5243,6 +5636,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5579,6 +5976,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5677,6 +6078,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5722,6 +6125,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -5809,6 +6248,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5907,6 +6350,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6013,6 +6458,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6648,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6299,6 +6750,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6344,6 +6797,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -6431,6 +6920,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6529,6 +7022,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6824,6 +7319,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6922,6 +7421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6967,6 +7468,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -7054,6 +7591,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7152,6 +7693,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7427,6 +7970,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7525,6 +8072,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7570,14 +8119,50 @@ spec: required: - repoURL type: object - sources: - items: - properties: - chart: - type: string - directory: - properties: - exclude: + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: type: string include: type: string @@ -7657,6 +8242,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7755,6 +8344,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8055,6 +8646,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8153,6 +8748,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8198,6 +8795,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8285,6 +8918,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8383,6 +9020,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8489,6 +9128,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +9318,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8775,6 +9420,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8820,6 +9467,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8907,6 +9590,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9005,6 +9692,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9300,6 +9989,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9398,6 +10091,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9443,6 +10138,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -9530,6 +10261,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9628,6 +10363,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9903,6 +10640,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10001,6 +10742,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10046,6 +10789,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10133,6 +10912,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10231,6 +11014,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10514,6 +11299,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10612,6 +11401,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10657,6 +11448,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10744,6 +11571,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10842,6 +11673,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11344,6 +12177,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11442,6 +12279,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11487,6 +12326,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -11574,6 +12449,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11672,6 +12551,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12169,6 +13050,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12267,6 +13152,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12312,6 +13199,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -12399,6 +13322,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12497,6 +13424,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12789,6 +13718,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12887,6 +13820,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12932,6 +13867,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13019,6 +13990,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13117,6 +14092,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13419,6 +14396,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13517,6 +14498,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13562,6 +14545,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13649,6 +14668,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13747,6 +14770,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13853,6 +14878,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +15068,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14139,6 +15170,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14184,6 +15217,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14271,6 +15340,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14369,6 +15442,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14664,6 +15739,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14762,6 +15841,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14807,6 +15888,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14894,6 +16011,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14992,6 +16113,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15267,6 +16390,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15365,6 +16492,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15410,6 +16539,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -15497,6 +16662,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15595,6 +16764,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15878,6 +17049,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15976,6 +17151,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16019,7 +17196,43 @@ spec: targetRevision: type: string required: - - repoURL + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource type: object sources: items: @@ -16108,6 +17321,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16206,6 +17423,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16708,6 +17927,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16806,6 +18029,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16851,6 +18076,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -16938,6 +18199,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17036,6 +18301,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17533,6 +18800,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17631,6 +18902,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17676,6 +18949,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -17763,6 +19072,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17861,6 +19174,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18157,6 +19472,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18255,6 +19574,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18300,6 +19621,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18387,6 +19744,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18485,6 +19846,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18767,6 +20130,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18865,6 +20232,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18910,6 +20279,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18997,6 +20402,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19095,6 +20504,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19597,6 +21008,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19695,6 +21110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19740,6 +21157,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -19827,6 +21280,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19925,6 +21382,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20422,6 +21881,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20520,6 +21983,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20565,6 +22030,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -20652,6 +22153,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20750,6 +22255,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21117,6 +22624,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21215,6 +22726,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21260,6 +22773,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -21347,6 +22896,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21445,6 +22998,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21604,6 +23159,9 @@ spec: type: string health: properties: + lastTransitionTime: + format: date-time + type: string message: type: string status: @@ -21617,6 +23175,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +23295,7 @@ spec: sync operation. properties: defaultServiceAccount: - description: ServiceAccountName to be used for impersonation + description: DefaultServiceAccount to be used for impersonation during the sync operation type: string namespace: @@ -21746,6 +23306,9 @@ spec: description: Server specifies the URL of the target cluster's Kubernetes control plane API. type: string + required: + - defaultServiceAccount + - server type: object type: array destinations: @@ -23841,6 +25404,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -23901,6 +25470,12 @@ spec: key: applicationsetcontroller.webhook.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -23931,6 +25506,8 @@ spec: name: tmp - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-applicationset-controller volumes: - configMap: @@ -24053,6 +25630,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -24142,6 +25721,8 @@ spec: - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls workingDir: /app + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true seccompProfile: @@ -24452,6 +26033,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -24590,6 +26177,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -24930,6 +26519,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -24973,6 +26568,8 @@ spec: name: tmp - mountPath: /home/argocd/params name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -25130,6 +26727,30 @@ spec: key: controller.self.heal.timeout.seconds name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -25238,6 +26859,14 @@ spec: key: controller.ignore.normalizer.jq.timeout name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -25265,11 +26894,17 @@ spec: name: argocd-home - mountPath: /home/argocd/params name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-application-controller volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: items: @@ -25392,7 +27027,13 @@ spec: name: argocd-redis image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent - lifecycle: {} + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - sleep 30; redis-cli -p 26379 sentinel reset argocd livenessProbe: exec: command: diff --git a/manifests/ha/namespace-install-with-hydrator.yaml b/manifests/ha/namespace-install-with-hydrator.yaml new file mode 100644 index 0000000000000..5f8316a33220b --- /dev/null +++ b/manifests/ha/namespace-install-with-hydrator.yaml @@ -0,0 +1,3788 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +secrets: +- name: argocd-redis +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resourceNames: + - argocd-notifications-cm + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resourceNames: + - argocd-notifications-secret + resources: + - secrets + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +rules: +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-dex-server +subjects: +- kind: ServiceAccount + name: argocd-dex-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-notifications-controller +subjects: +- kind: ServiceAccount + name: argocd-notifications-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis-ha +subjects: +- kind: ServiceAccount + name: argocd-redis-ha +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis-ha-haproxy +subjects: +- kind: ServiceAccount + name: argocd-redis-ha-haproxy +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cm + app.kubernetes.io/part-of: argocd + name: argocd-cm +--- +apiVersion: v1 +data: + redis.server: argocd-redis-ha-haproxy:6379 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cmd-params-cm + app.kubernetes.io/part-of: argocd + name: argocd-cmd-params-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-gpg-keys-cm + app.kubernetes.io/part-of: argocd + name: argocd-gpg-keys-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-rbac-cm + app.kubernetes.io/part-of: argocd + name: argocd-rbac-cm +--- +apiVersion: v1 +data: + fix-split-brain.sh: | + HOSTNAME="$(hostname)" + INDEX="${HOSTNAME##*-}" + SENTINEL_PORT=26379 + ANNOUNCE_IP='' + MASTER='' + MASTER_GROUP="argocd" + QUORUM="2" + REDIS_CONF=/data/conf/redis.conf + REDIS_PORT=6379 + REDIS_TLS_PORT= + SENTINEL_CONF=/data/conf/sentinel.conf + SENTINEL_TLS_PORT= + SERVICE=argocd-redis-ha + SENTINEL_TLS_REPLICATION_ENABLED=false + REDIS_TLS_REPLICATION_ENABLED=false + + ROLE='' + REDIS_MASTER='' + + set -eu + sentinel_get_master() { + set +e + if [ "$SENTINEL_PORT" -eq 0 ]; then + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + else + redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + fi + set -e + } + + sentinel_get_master_retry() { + master='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + master=$(sentinel_get_master) + if [ -n "${master}" ]; then + break + fi + sleep $((sleep + i)) + done + echo "${master}" + } + + identify_master() { + echo "Identifying redis master (get-master-addr-by-name).." + echo " using sentinel (argocd-redis-ha), sentinel group name (argocd)" + MASTER="$(sentinel_get_master_retry 3)" + if [ -n "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + else + echo " $(date) Did not find redis master (${MASTER})" + fi + } + + sentinel_update() { + echo "Updating sentinel config.." + echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})" + eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}" + echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})" + sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}" + if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then + echo " redis master (${1}:${REDIS_TLS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + else + echo " redis master (${1}:${REDIS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + fi + echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF} + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})" + echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF} + else + echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})" + echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF} + fi + } + + redis_update() { + echo "Updating redis config.." + if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then + echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})" + echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF} + else + echo " we are slave of redis master (${1}:${REDIS_PORT})" + echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF} + fi + echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF} + } + + copy_config() { + echo "Copying default redis config.." + echo " to '${REDIS_CONF}'" + cp /readonly-config/redis.conf "${REDIS_CONF}" + echo "Copying default sentinel config.." + echo " to '${SENTINEL_CONF}'" + cp /readonly-config/sentinel.conf "${SENTINEL_CONF}" + } + + setup_defaults() { + echo "Setting up defaults.." + echo " using statefulset index (${INDEX})" + if [ "${INDEX}" = "0" ]; then + echo "Setting this pod as master for redis and sentinel.." + echo " using announce (${ANNOUNCE_IP})" + redis_update "${ANNOUNCE_IP}" + sentinel_update "${ANNOUNCE_IP}" + echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)" + sed -i "s/^.*slaveof.*//" "${REDIS_CONF}" + else + echo "Getting redis master ip.." + echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master" + DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')" + if [ -z "${DEFAULT_MASTER}" ]; then + echo "Error: Unable to resolve redis master (getent hosts)." + exit 1 + fi + echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})" + echo "Setting default slave config for redis and sentinel.." + echo " using master ip (${DEFAULT_MASTER})" + redis_update "${DEFAULT_MASTER}" + sentinel_update "${DEFAULT_MASTER}" + fi + } + + redis_ping() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + else + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping + fi + set -e + } + + redis_ping_retry() { + ping='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + if [ "$(redis_ping)" = "PONG" ]; then + ping='PONG' + break + fi + sleep $((sleep + i)) + MASTER=$(sentinel_get_master) + done + echo "${ping}" + } + + find_master() { + echo "Verifying redis master.." + if [ "$REDIS_PORT" -eq 0 ]; then + echo " ping (${MASTER}:${REDIS_TLS_PORT})" + else + echo " ping (${MASTER}:${REDIS_PORT})" + fi + if [ "$(redis_ping_retry 3)" != "PONG" ]; then + echo " $(date) Can't ping redis master (${MASTER})" + echo "Attempting to force failover (sentinel failover).." + + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + else + echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + fi + + echo "Hold on for 10sec" + sleep 10 + echo "We should get redis master's ip now. Asking (get-master-addr-by-name).." + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + else + echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + fi + MASTER="$(sentinel_get_master)" + if [ "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + else + echo "$(date) Error: Could not failover, exiting..." + exit 1 + fi + else + echo " $(date) Found reachable redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + fi + } + + redis_ro_update() { + echo "Updating read-only redis config.." + echo " redis.conf set 'replica-priority 0'" + echo "replica-priority 0" >> ${REDIS_CONF} + } + + getent_hosts() { + index=${1:-${INDEX}} + service="${SERVICE}-announce-${index}" + host=$(getent hosts "${service}") + echo "${host}" + } + + identify_announce_ip() { + echo "Identify announce ip for this pod.." + echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})" + ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }') + echo " identified announce (${ANNOUNCE_IP})" + } + + redis_role() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep role | sed 's/role://' | sed 's/\r//') + else + ROLE=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//') + fi + set -e + } + + identify_redis_master() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key info | grep master_host | sed 's/master_host://' | sed 's/\r//') + else + REDIS_MASTER=$(redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//') + fi + set -e + } + + reinit() { + set +e + sh /readonly-config/init.sh + + if [ "$REDIS_PORT" -eq 0 ]; then + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key + else + echo "shutdown" | redis-cli -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" + fi + set -e + } + + identify_announce_ip + + while [ -z "${ANNOUNCE_IP}" ]; do + echo "Error: Could not resolve the announce ip for this pod." + sleep 30 + identify_announce_ip + done + + trap "exit 0" TERM + while true; do + sleep 60 + + # where is redis master + identify_master + + if [ "$MASTER" = "$ANNOUNCE_IP" ]; then + redis_role + if [ "$ROLE" != "master" ]; then + reinit + fi + elif [ "${MASTER}" ]; then + identify_redis_master + if [ "$REDIS_MASTER" != "$MASTER" ]; then + reinit + fi + fi + done + haproxy.cfg: "defaults REDIS\n mode tcp\n timeout connect 4s\n timeout server + 6m\n timeout client 6m\n timeout check 2s\n\nlisten health_check_http_url\n + \ bind :8888 \n mode http\n monitor-uri /healthz\n option dontlognull\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_0\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE0\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_1\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE1\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n# + Check Sentinel and whether they are nominated master\nbackend check_if_redis_is_master_2\n + \ mode tcp\n option tcp-check\n tcp-check connect\n tcp-check send PING\\r\\n\n + \ tcp-check expect string +PONG\n tcp-check send SENTINEL\\ get-master-addr-by-name\\ + argocd\\r\\n\n tcp-check expect string REPLACE_ANNOUNCE2\n tcp-check send QUIT\\r\\n\n + \ server R0 argocd-redis-ha-announce-0:26379 check inter 3s\n server R1 argocd-redis-ha-announce-1:26379 + check inter 3s\n server R2 argocd-redis-ha-announce-2:26379 check inter 3s\n\n# + decide redis backend to use\n#master\nfrontend ft_redis_master\n bind :6379 \n + \ use_backend bk_redis_master\n# Check all redis servers to see if they think + they are master\nbackend bk_redis_master\n mode tcp\n option tcp-check\n tcp-check + connect\n tcp-check send \"AUTH ${AUTH}\"\\r\\n\n tcp-check expect string +OK\n + \ tcp-check send PING\\r\\n\n tcp-check expect string +PONG\n tcp-check send + info\\ replication\\r\\n\n tcp-check expect string role:master\n tcp-check send + QUIT\\r\\n\n tcp-check expect string +OK\n use-server R0 if { srv_is_up(R0) + } { nbsrv(check_if_redis_is_master_0) ge 2 }\n server R0 argocd-redis-ha-announce-0:6379 + check inter 3s fall 1 rise 1\n use-server R1 if { srv_is_up(R1) } { nbsrv(check_if_redis_is_master_1) + ge 2 }\n server R1 argocd-redis-ha-announce-1:6379 check inter 3s fall 1 rise + 1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge + 2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend + stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter + if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n" + haproxy_init.sh: | + HAPROXY_CONF=/data/haproxy.cfg + cp /readonly/haproxy.cfg "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-0 && break + echo "Waiting for service argocd-redis-ha-announce-0 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP0=$(getent hosts "argocd-redis-ha-announce-0" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP0" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-0" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE0/$ANNOUNCE_IP0/" "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-1 && break + echo "Waiting for service argocd-redis-ha-announce-1 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP1=$(getent hosts "argocd-redis-ha-announce-1" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP1" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-1" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE1/$ANNOUNCE_IP1/" "$HAPROXY_CONF" + for loop in $(seq 1 10); do + getent hosts argocd-redis-ha-announce-2 && break + echo "Waiting for service argocd-redis-ha-announce-2 to be ready ($loop) ..." && sleep 1 + done + ANNOUNCE_IP2=$(getent hosts "argocd-redis-ha-announce-2" | awk '{ print $1 }') + if [ -z "$ANNOUNCE_IP2" ]; then + echo "Could not resolve the announce ip for argocd-redis-ha-announce-2" + exit 1 + fi + sed -i "s/REPLACE_ANNOUNCE2/$ANNOUNCE_IP2/" "$HAPROXY_CONF" + init.sh: | + echo "$(date) Start..." + HOSTNAME="$(hostname)" + INDEX="${HOSTNAME##*-}" + SENTINEL_PORT=26379 + ANNOUNCE_IP='' + MASTER='' + MASTER_GROUP="argocd" + QUORUM="2" + REDIS_CONF=/data/conf/redis.conf + REDIS_PORT=6379 + REDIS_TLS_PORT= + SENTINEL_CONF=/data/conf/sentinel.conf + SENTINEL_TLS_PORT= + SERVICE=argocd-redis-ha + SENTINEL_TLS_REPLICATION_ENABLED=false + REDIS_TLS_REPLICATION_ENABLED=false + + set -eu + sentinel_get_master() { + set +e + if [ "$SENTINEL_PORT" -eq 0 ]; then + redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + else + redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel get-master-addr-by-name "${MASTER_GROUP}" |\ + grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))' + fi + set -e + } + + sentinel_get_master_retry() { + master='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + master=$(sentinel_get_master) + if [ -n "${master}" ]; then + break + fi + sleep $((sleep + i)) + done + echo "${master}" + } + + identify_master() { + echo "Identifying redis master (get-master-addr-by-name).." + echo " using sentinel (argocd-redis-ha), sentinel group name (argocd)" + MASTER="$(sentinel_get_master_retry 3)" + if [ -n "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + else + echo " $(date) Did not find redis master (${MASTER})" + fi + } + + sentinel_update() { + echo "Updating sentinel config.." + echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})" + eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}" + echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})" + sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}" + if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then + echo " redis master (${1}:${REDIS_TLS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + else + echo " redis master (${1}:${REDIS_PORT})" + sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}" + fi + echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF} + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})" + echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF} + else + echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})" + echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF} + fi + } + + redis_update() { + echo "Updating redis config.." + if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then + echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})" + echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF} + else + echo " we are slave of redis master (${1}:${REDIS_PORT})" + echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}" + echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF} + fi + echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF} + } + + copy_config() { + echo "Copying default redis config.." + echo " to '${REDIS_CONF}'" + cp /readonly-config/redis.conf "${REDIS_CONF}" + echo "Copying default sentinel config.." + echo " to '${SENTINEL_CONF}'" + cp /readonly-config/sentinel.conf "${SENTINEL_CONF}" + } + + setup_defaults() { + echo "Setting up defaults.." + echo " using statefulset index (${INDEX})" + if [ "${INDEX}" = "0" ]; then + echo "Setting this pod as master for redis and sentinel.." + echo " using announce (${ANNOUNCE_IP})" + redis_update "${ANNOUNCE_IP}" + sentinel_update "${ANNOUNCE_IP}" + echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)" + sed -i "s/^.*slaveof.*//" "${REDIS_CONF}" + else + echo "Getting redis master ip.." + echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master" + DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')" + if [ -z "${DEFAULT_MASTER}" ]; then + echo "Error: Unable to resolve redis master (getent hosts)." + exit 1 + fi + echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})" + echo "Setting default slave config for redis and sentinel.." + echo " using master ip (${DEFAULT_MASTER})" + redis_update "${DEFAULT_MASTER}" + sentinel_update "${DEFAULT_MASTER}" + fi + } + + redis_ping() { + set +e + if [ "$REDIS_PORT" -eq 0 ]; then + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key ping + else + redis-cli -h "${MASTER}" -a "${AUTH}" --no-auth-warning -p "${REDIS_PORT}" ping + fi + set -e + } + + redis_ping_retry() { + ping='' + retry=${1} + sleep=3 + for i in $(seq 1 "${retry}"); do + if [ "$(redis_ping)" = "PONG" ]; then + ping='PONG' + break + fi + sleep $((sleep + i)) + MASTER=$(sentinel_get_master) + done + echo "${ping}" + } + + find_master() { + echo "Verifying redis master.." + if [ "$REDIS_PORT" -eq 0 ]; then + echo " ping (${MASTER}:${REDIS_TLS_PORT})" + else + echo " ping (${MASTER}:${REDIS_PORT})" + fi + if [ "$(redis_ping_retry 3)" != "PONG" ]; then + echo " $(date) Can't ping redis master (${MASTER})" + echo "Attempting to force failover (sentinel failover).." + + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" --tls --cacert /tls-certs/ca.crt --cert /tls-certs/redis.crt --key /tls-certs/redis.key sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + else + echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then + echo " $(date) Failover returned with 'NOGOODSLAVE'" + echo "Setting defaults for this pod.." + setup_defaults + return 0 + fi + fi + + echo "Hold on for 10sec" + sleep 10 + echo "We should get redis master's ip now. Asking (get-master-addr-by-name).." + if [ "$SENTINEL_PORT" -eq 0 ]; then + echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})" + else + echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})" + fi + MASTER="$(sentinel_get_master)" + if [ "${MASTER}" ]; then + echo " $(date) Found redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + else + echo "$(date) Error: Could not failover, exiting..." + exit 1 + fi + else + echo " $(date) Found reachable redis master (${MASTER})" + echo "Updating redis and sentinel config.." + sentinel_update "${MASTER}" + redis_update "${MASTER}" + fi + } + + redis_ro_update() { + echo "Updating read-only redis config.." + echo " redis.conf set 'replica-priority 0'" + echo "replica-priority 0" >> ${REDIS_CONF} + } + + getent_hosts() { + index=${1:-${INDEX}} + service="${SERVICE}-announce-${index}" + host=$(getent hosts "${service}") + echo "${host}" + } + + identify_announce_ip() { + echo "Identify announce ip for this pod.." + echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})" + ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }') + echo " identified announce (${ANNOUNCE_IP})" + } + + mkdir -p /data/conf/ + + echo "Initializing config.." + copy_config + + # where is redis master + identify_master + + identify_announce_ip + + if [ -z "${ANNOUNCE_IP}" ]; then + "Error: Could not resolve the announce ip for this pod." + exit 1 + elif [ "${MASTER}" ]; then + find_master + else + setup_defaults + fi + + if [ "${AUTH:-}" ]; then + echo "Setting redis auth values.." + ESCAPED_AUTH=$(echo "${AUTH}" | sed -e 's/[\/&]/\\&/g'); + sed -i "s/replace-default-auth/${ESCAPED_AUTH}/" "${REDIS_CONF}" "${SENTINEL_CONF}" + fi + + if [ "${SENTINELAUTH:-}" ]; then + echo "Setting sentinel auth values" + ESCAPED_AUTH_SENTINEL=$(echo "$SENTINELAUTH" | sed -e 's/[\/&]/\\&/g'); + sed -i "s/replace-default-sentinel-auth/${ESCAPED_AUTH_SENTINEL}/" "$SENTINEL_CONF" + fi + + echo "$(date) Ready..." + redis.conf: | + dir "/data" + port 6379 + rename-command FLUSHDB "" + rename-command FLUSHALL "" + bind 0.0.0.0 + maxmemory 0 + maxmemory-policy volatile-lru + min-replicas-max-lag 5 + min-replicas-to-write 1 + rdbchecksum yes + rdbcompression yes + repl-diskless-sync yes + save "" + requirepass replace-default-auth + masterauth replace-default-auth + sentinel.conf: | + dir "/data" + port 26379 + bind 0.0.0.0 + sentinel down-after-milliseconds argocd 10000 + sentinel failover-timeout argocd 180000 + maxclients 10000 + sentinel parallel-syncs argocd 5 + sentinel auth-pass argocd replace-default-auth + trigger-failover-if-master.sh: | + get_redis_role() { + is_master=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + info | grep -c 'role:master' || true + ) + } + get_redis_role + if [[ "$is_master" -eq 1 ]]; then + echo "This node is currently master, we trigger a failover." + response=$( + redis-cli \ + -h localhost \ + -p 26379 \ + SENTINEL failover argocd + ) + if [[ "$response" != "OK" ]] ; then + echo "$response" + exit 1 + fi + timeout=30 + while [[ "$is_master" -eq 1 && $timeout -gt 0 ]]; do + sleep 1 + get_redis_role + timeout=$((timeout - 1)) + done + echo "Failover successful" + fi +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-configmap +--- +apiVersion: v1 +data: + redis_liveness.sh: | + response=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + ping + ) + if [ "$response" != "PONG" ] && [ "${response:0:7}" != "LOADING" ] ; then + echo "$response" + exit 1 + fi + echo "response=$response" + redis_readiness.sh: | + response=$( + redis-cli \ + -a "${AUTH}" --no-auth-warning \ + -h localhost \ + -p 6379 \ + ping + ) + if [ "$response" != "PONG" ] ; then + echo "$response" + exit 1 + fi + echo "response=$response" + sentinel_liveness.sh: | + response=$( + redis-cli \ + -h localhost \ + -p 26379 \ + ping + ) + if [ "$response" != "PONG" ]; then + echo "$response" + exit 1 + fi + echo "response=$response" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-health-configmap +--- +apiVersion: v1 +data: + ssh_known_hosts: | + # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT + [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE= + bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-ssh-known-hosts-cm + app.kubernetes.io/part-of: argocd + name: argocd-ssh-known-hosts-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-tls-certs-cm + app.kubernetes.io/part-of: argocd + name: argocd-tls-certs-cm +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-secret +type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: argocd-secret + app.kubernetes.io/part-of: argocd + name: argocd-secret +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + ports: + - name: webhook + port: 7000 + protocol: TCP + targetPort: webhook + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + ports: + - name: server + port: 8086 + protocol: TCP + targetPort: 8086 + - name: metrics + port: 8087 + protocol: TCP + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + ports: + - appProtocol: TCP + name: http + port: 5556 + protocol: TCP + targetPort: 5556 + - name: grpc + port: 5557 + protocol: TCP + targetPort: 5557 + - name: metrics + port: 5558 + protocol: TCP + targetPort: 5558 + selector: + app.kubernetes.io/name: argocd-dex-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/name: argocd-metrics + app.kubernetes.io/part-of: argocd + name: argocd-metrics +spec: + ports: + - name: metrics + port: 8082 + protocol: TCP + targetPort: 8082 + selector: + app.kubernetes.io/name: argocd-application-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller-metrics + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-metrics +spec: + ports: + - name: metrics + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/name: argocd-notifications-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha +spec: + clusterIP: None + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + selector: + app.kubernetes.io/name: argocd-redis-ha + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-0 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-0 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-1 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-1 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-announce-2 +spec: + ports: + - name: tcp-server + port: 6379 + protocol: TCP + targetPort: redis + - name: tcp-sentinel + port: 26379 + protocol: TCP + targetPort: sentinel + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: argocd-redis-ha + statefulset.kubernetes.io/pod-name: argocd-redis-ha-server-2 + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +spec: + ports: + - name: tcp-haproxy + port: 6379 + protocol: TCP + targetPort: redis + - name: http-exporter-port + port: 9101 + protocol: TCP + targetPort: metrics-port + selector: + app.kubernetes.io/name: argocd-redis-ha-haproxy + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + ports: + - name: server + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 8084 + protocol: TCP + targetPort: 8084 + selector: + app.kubernetes.io/name: argocd-repo-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + - name: https + port: 443 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server-metrics + app.kubernetes.io/part-of: argocd + name: argocd-server-metrics +spec: + ports: + - name: metrics + port: 8083 + protocol: TCP + targetPort: 8083 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-applicationset-controller + env: + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.annotations + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.labels + name: argocd-cmd-params-cm + optional: true + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.policy.override + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_CONCURRENT_RECONCILIATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.concurrent.reconciliations.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-applicationset-controller + ports: + - containerPort: 7000 + name: webhook + - containerPort: 8080 + name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-applicationset-controller + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: commitserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: commitserver.log.level + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-commit-server + ports: + - containerPort: 8086 + - containerPort: 8087 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + serviceAccountName: argocd-commit-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-commit-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-dex-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - command: + - /shared/argocd-dex + - rundex + env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: dexserver.disable.tls + name: argocd-cmd-params-cm + optional: true + image: ghcr.io/dexidp/dex:v2.41.1 + imagePullPolicy: Always + name: dex + ports: + - containerPort: 5556 + - containerPort: 5557 + - containerPort: 5558 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + - mountPath: /tls + name: argocd-dex-server-tls + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /shared/argocd-dex + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-dex-server + volumes: + - emptyDir: {} + name: static-files + - emptyDir: {} + name: dexconfig + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: argocd-notifications-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-notifications + env: + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + tcpSocket: + port: 9001 + name: argocd-notifications-controller + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + workingDir: /app + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-notifications-controller + volumes: + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha-haproxy + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-haproxy +spec: + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + strategy: + type: RollingUpdate + template: + metadata: + annotations: + checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54 + prometheus.io/path: /metrics + prometheus.io/port: "9101" + prometheus.io/scrape: "true" + labels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + name: argocd-redis-ha-haproxy + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + topologyKey: kubernetes.io/hostname + containers: + - env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine + imagePullPolicy: IfNotPresent + lifecycle: {} + livenessProbe: + httpGet: + path: /healthz + port: 8888 + initialDelaySeconds: 5 + periodSeconds: 3 + name: haproxy + ports: + - containerPort: 6379 + name: redis + - containerPort: 9101 + name: metrics-port + readinessProbe: + httpGet: + path: /healthz + port: 8888 + initialDelaySeconds: 5 + periodSeconds: 3 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /usr/local/etc/haproxy + name: data + - mountPath: /run/haproxy + name: shared-socket + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + - args: + - /readonly/haproxy_init.sh + command: + - sh + image: public.ecr.aws/docker/library/haproxy:2.6.17-alpine + imagePullPolicy: IfNotPresent + name: config-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly + name: config-volume + readOnly: true + - mountPath: /data + name: data + securityContext: + fsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + serviceAccountName: argocd-redis-ha-haproxy + volumes: + - configMap: + name: argocd-redis-ha-configmap + name: config-volume + - emptyDir: {} + name: shared-socket + - emptyDir: {} + name: data +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-repo-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: kubernetes.io/hostname + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-repo-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: reposerver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: reposerver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_METRICS_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: reposerver.disable.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: reposerver.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.repo.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.max.combined.directory.manifests.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.tar.exclusions + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.disable.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.revision.cache.lock.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GRPC_MAX_SIZE_MB + valueFrom: + configMapKeyRef: + key: reposerver.grpc.max.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES + valueFrom: + configMapKeyRef: + key: reposerver.include.hidden.directories + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8084 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-repo-server + ports: + - containerPort: 8081 + - containerPort: 8084 + readinessProbe: + httpGet: + path: /healthz + port: 8084 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /tmp + name: tmp + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-repo-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - emptyDir: {} + name: helm-working-dir + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - emptyDir: {} + name: var-files + - emptyDir: {} + name: plugins +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: argocd-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: kubernetes.io/hostname + containers: + - args: + - /usr/local/bin/argocd-server + env: + - name: ARGOCD_API_SERVER_REPLICAS + value: "2" + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + key: server.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + key: server.basehref + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + key: server.rootpath + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: server.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + key: server.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + key: server.dex.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + key: server.disable.auth + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + key: server.enable.gzip + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: server.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + key: server.x.frame.options + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + key: server.content.security.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.dex.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.dex.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: server.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.connection.status.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.oidc.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.login.attempts.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + key: server.staticassets + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + key: server.http.cookie.maxnumber + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + key: server.enable.proxy.extension + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-server + ports: + - containerPort: 8080 + - containerPort: 8083 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/server/tls + name: argocd-repo-server-tls + - mountPath: /app/config/dex/tls + name: argocd-dex-server-tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /tmp + name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-server + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + serviceName: argocd-application-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-application-controller + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-application-controller + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_CONTROLLER_REPLICAS + value: "1" + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.hard.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.status.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.operation.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: controller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: controller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.metrics.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: controller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: controller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + key: controller.resource.health.persist + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM + valueFrom: + configMapKeyRef: + key: controller.sharding.algorithm + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: controller.kubectl.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.ignore.normalizer.jq.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-application-controller + ports: + - containerPort: 8082 + readinessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp + workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-application-controller + volumes: + - emptyDir: {} + name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis-ha + app.kubernetes.io/part-of: argocd + name: argocd-redis-ha-server +spec: + podManagementPolicy: OrderedReady + replicas: 3 + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + serviceName: argocd-redis-ha + template: + metadata: + annotations: + checksum/init-config: 9d3c019a5ea1fd98ab5cde397d8eecd351da884f15e6ba346c607cb2446c2198 + labels: + app.kubernetes.io/name: argocd-redis-ha + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + topologyKey: kubernetes.io/hostname + automountServiceAccountToken: false + containers: + - args: + - /data/conf/redis.conf + command: + - redis-server + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /bin/sh + - /readonly-config/trigger-failover-if-master.sh + livenessProbe: + exec: + command: + - sh + - -c + - /health/redis_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + name: redis + ports: + - containerPort: 6379 + name: redis + readinessProbe: + exec: + command: + - sh + - -c + - /health/redis_readiness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + - mountPath: /health + name: health + - args: + - /data/conf/sentinel.conf + command: + - redis-sentinel + env: + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - sleep 30; redis-cli -p 26379 sentinel reset argocd + livenessProbe: + exec: + command: + - sh + - -c + - /health/sentinel_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 15 + name: sentinel + ports: + - containerPort: 26379 + name: sentinel + readinessProbe: + exec: + command: + - sh + - -c + - /health/sentinel_liveness.sh + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 3 + timeoutSeconds: 15 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + - mountPath: /health + name: health + - args: + - /readonly-config/fix-split-brain.sh + command: + - sh + env: + - name: SENTINEL_ID_0 + value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 + - name: SENTINEL_ID_1 + value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 + - name: SENTINEL_ID_2 + value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + name: split-brain-fix + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + initContainers: + - args: + - /readonly-config/init.sh + command: + - sh + env: + - name: SENTINEL_ID_0 + value: 3c0d9c0320bb34888c2df5757c718ce6ca992ce6 + - name: SENTINEL_ID_1 + value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 + - name: SENTINEL_ID_2 + value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca + - name: AUTH + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: public.ecr.aws/docker/library/redis:7.0.15-alpine + imagePullPolicy: IfNotPresent + name: config-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /readonly-config + name: config + readOnly: true + - mountPath: /data + name: data + securityContext: + fsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccountName: argocd-redis-ha + terminationGracePeriodSeconds: 60 + volumes: + - configMap: + name: argocd-redis-ha-configmap + name: config + - configMap: + defaultMode: 493 + name: argocd-redis-ha-health-configmap + name: health + - emptyDir: {} + name: data + updateStrategy: + type: RollingUpdate +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-application-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8082 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-applicationset-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 7000 + protocol: TCP + - port: 8080 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-commit-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 8086 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8087 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-dex-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + ports: + - port: 5556 + protocol: TCP + - port: 5557 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 5558 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 9001 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-ha-proxy-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-ha-server-network-policy +spec: + egress: + - ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + to: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + ports: + - port: 6379 + protocol: TCP + - port: 26379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-repo-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + ports: + - port: 8081 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8084 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-server-network-policy +spec: + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + policyTypes: + - Ingress diff --git a/manifests/ha/namespace-install-with-hydrator/kustomization.yaml b/manifests/ha/namespace-install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..ecde0d9c70796 --- /dev/null +++ b/manifests/ha/namespace-install-with-hydrator/kustomization.yaml @@ -0,0 +1,3 @@ +resources: + - ../namespace-install + - ../../base/commit-server diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index deefe124a2048..d86dfd009f8d7 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -1634,6 +1634,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -1694,6 +1700,12 @@ spec: key: applicationsetcontroller.webhook.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -1724,6 +1736,8 @@ spec: name: tmp - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-applicationset-controller volumes: - configMap: @@ -1846,6 +1860,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -1935,6 +1951,8 @@ spec: - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls workingDir: /app + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true seccompProfile: @@ -2245,6 +2263,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -2383,6 +2407,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -2723,6 +2749,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -2766,6 +2798,8 @@ spec: name: tmp - mountPath: /home/argocd/params name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -2923,6 +2957,30 @@ spec: key: controller.self.heal.timeout.seconds name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -3031,6 +3089,14 @@ spec: key: controller.ignore.normalizer.jq.timeout name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -3058,11 +3124,17 @@ spec: name: argocd-home - mountPath: /home/argocd/params name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-application-controller volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: items: @@ -3185,7 +3257,13 @@ spec: name: argocd-redis image: public.ecr.aws/docker/library/redis:7.0.15-alpine imagePullPolicy: IfNotPresent - lifecycle: {} + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - sleep 30; redis-cli -p 26379 sentinel reset argocd livenessProbe: exec: command: diff --git a/manifests/install-with-hydrator.yaml b/manifests/install-with-hydrator.yaml new file mode 100644 index 0000000000000..446762e6c0da5 --- /dev/null +++ b/manifests/install-with-hydrator.yaml @@ -0,0 +1,26352 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + - jsonPath: .spec.project + name: Project + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to + apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: |- + Project is a reference to the project this application belongs to. + The empty string means that application belongs to the 'default' project. + type: string + revisionHistoryLimit: + description: |- + RevisionHistoryLimit limits the number of items kept in the application's revision history, which is used for informational purposes as well as for rollbacks to previous versions. + This should only be changed in exceptional circumstances. + Setting to zero will store no history. This will reduce storage used. + Increasing will increase the space used to store the history, so we do not recommend increasing it. + Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether to + apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize adds + to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether to apply + common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifies whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usually an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string + health: + description: Health contains information about the application's current + health status + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: |- + ObservedAt indicates when the application state was updated without querying latest git state + Deprecated: controller no longer updates ObservedAt field + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: |- + Revision is the revision (Git) or chart version (Helm) which to sync the application to + If omitted, will use the revision specified in app spec. + type: string + revisions: + description: |- + Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to + If omitted, will use the revision specified in app spec. + items: + type: string + type: array + source: + description: |- + Source overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over + Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors + or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: |- + Sources overrides the source definition set in the application. + This is typically set in a Rollback operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block. ValuesObject takes precedence + over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies + whether to apply common labels to resource + selectors or not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize + Replicas override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: |- + Force indicates whether or not to supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, when PATCH encounters conflict and has + retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + managedNamespaceMetadata: + description: ManagedNamespaceMetadata contains the current + sync state of managed namespace metadata + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: |- + HookPhase contains the state of any operation associated with this resource OR hook + This can also contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: |- + ResourceStatus holds the current sync and health status of a resource + TODO: describe members of this type + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name. This must be set + if Server is not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: |- + ManagedFieldsManagers is a list of trusted managers. Fields mutated by those managers will take precedence over the + desired state defined in the SCM and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + labelWithoutSelector: + description: LabelWithoutSelector specifies whether + to apply common labels to resource selectors or + not + type: boolean + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: |- + TargetRevision defines the revision of the source to sync the application to. + In case of Git, this can be commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyNestedSelectors: + type: boolean + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + flatList: + type: boolean + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + goTemplate: + type: boolean + goTemplateOptions: + items: + type: string + type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array + preservedFields: + properties: + annotations: + items: + type: string + type: array + labels: + items: + type: string + type: array + type: object + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + apiVersions: + items: + type: string + type: array + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + kubeVersion: + type: string + namespace: + type: string + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + apiVersions: + items: + type: string + type: array + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + components: + items: + type: string + type: array + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + kubeVersion: + type: string + labelWithoutSelector: + type: boolean + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + name: + type: string + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + templatePatch: + type: string + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + targetRevisions: + items: + type: string + type: array + required: + - application + - message + - status + - step + - targetRevisions + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + resources: + items: + properties: + group: + type: string + health: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresDeletionConfirmation: + type: boolean + requiresPruning: + type: boolean + status: + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + AppProject provides a logical grouping of applications, providing controls for: + * where the apps may deploy to (cluster whitelist) + * what may be deployed (repository whitelist, resource whitelist/blacklist) + * who can access these applications (roles, OIDC group claims bindings) + * and what they can do (RBAC policies) + * automation access to these roles (JWT tokens) + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: DefaultServiceAccount to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + required: + - defaultServiceAccount + - server + type: object + type: array + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: |- + Namespace specifies the target namespace for the application's resources. + The namespace will only be set for namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: |- + GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying + concepts during lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resourceNames: + - argocd-notifications-cm + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resourceNames: + - argocd-notifications-secret + resources: + - secrets + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - delete + - get + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - list +- apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create +- apiGroups: + - argoproj.io + resources: + - workflows + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-dex-server +subjects: +- kind: ServiceAccount + name: argocd-dex-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-notifications-controller +subjects: +- kind: ServiceAccount + name: argocd-notifications-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server + namespace: argocd +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cm + app.kubernetes.io/part-of: argocd + name: argocd-cm +--- +apiVersion: v1 +data: + hydrator.enabled: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cmd-params-cm + app.kubernetes.io/part-of: argocd + name: argocd-cmd-params-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-gpg-keys-cm + app.kubernetes.io/part-of: argocd + name: argocd-gpg-keys-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-rbac-cm + app.kubernetes.io/part-of: argocd + name: argocd-rbac-cm +--- +apiVersion: v1 +data: + ssh_known_hosts: | + # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT + [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE= + bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-ssh-known-hosts-cm + app.kubernetes.io/part-of: argocd + name: argocd-ssh-known-hosts-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-tls-certs-cm + app.kubernetes.io/part-of: argocd + name: argocd-tls-certs-cm +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-secret +type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: argocd-secret + app.kubernetes.io/part-of: argocd + name: argocd-secret +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + ports: + - name: webhook + port: 7000 + protocol: TCP + targetPort: webhook + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + ports: + - name: server + port: 8086 + protocol: TCP + targetPort: 8086 + - name: metrics + port: 8087 + protocol: TCP + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + ports: + - appProtocol: TCP + name: http + port: 5556 + protocol: TCP + targetPort: 5556 + - name: grpc + port: 5557 + protocol: TCP + targetPort: 5557 + - name: metrics + port: 5558 + protocol: TCP + targetPort: 5558 + selector: + app.kubernetes.io/name: argocd-dex-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/name: argocd-metrics + app.kubernetes.io/part-of: argocd + name: argocd-metrics +spec: + ports: + - name: metrics + port: 8082 + protocol: TCP + targetPort: 8082 + selector: + app.kubernetes.io/name: argocd-application-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller-metrics + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-metrics +spec: + ports: + - name: metrics + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/name: argocd-notifications-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + ports: + - name: tcp-redis + port: 6379 + targetPort: 6379 + selector: + app.kubernetes.io/name: argocd-redis +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + ports: + - name: server + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 8084 + protocol: TCP + targetPort: 8084 + selector: + app.kubernetes.io/name: argocd-repo-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + - name: https + port: 443 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server-metrics + app.kubernetes.io/part-of: argocd + name: argocd-server-metrics +spec: + ports: + - name: metrics + port: 8083 + protocol: TCP + targetPort: 8083 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-applicationset-controller + env: + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.annotations + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.labels + name: argocd-cmd-params-cm + optional: true + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.policy.override + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_CONCURRENT_RECONCILIATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.concurrent.reconciliations.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-applicationset-controller + ports: + - containerPort: 7000 + name: webhook + - containerPort: 8080 + name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-applicationset-controller + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: commitserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: commitserver.log.level + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-commit-server + ports: + - containerPort: 8086 + - containerPort: 8087 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + serviceAccountName: argocd-commit-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-commit-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-dex-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - command: + - /shared/argocd-dex + - rundex + env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: dexserver.disable.tls + name: argocd-cmd-params-cm + optional: true + image: ghcr.io/dexidp/dex:v2.41.1 + imagePullPolicy: Always + name: dex + ports: + - containerPort: 5556 + - containerPort: 5557 + - containerPort: 5558 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + - mountPath: /tls + name: argocd-dex-server-tls + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /shared/argocd-dex + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-dex-server + volumes: + - emptyDir: {} + name: static-files + - emptyDir: {} + name: dexconfig + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: argocd-notifications-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-notifications + env: + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + tcpSocket: + port: 9001 + name: argocd-notifications-controller + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + workingDir: /app + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-notifications-controller + volumes: + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis + template: + metadata: + labels: + app.kubernetes.io/name: argocd-redis + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - --save + - "" + - --appendonly + - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine + imagePullPolicy: Always + name: redis + ports: + - containerPort: 6379 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-redis +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-repo-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-repo-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: reposerver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: reposerver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_METRICS_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: reposerver.disable.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: reposerver.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.repo.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.max.combined.directory.manifests.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.tar.exclusions + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.disable.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.revision.cache.lock.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GRPC_MAX_SIZE_MB + valueFrom: + configMapKeyRef: + key: reposerver.grpc.max.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES + valueFrom: + configMapKeyRef: + key: reposerver.include.hidden.directories + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8084 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-repo-server + ports: + - containerPort: 8081 + - containerPort: 8084 + readinessProbe: + httpGet: + path: /healthz + port: 8084 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /tmp + name: tmp + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-repo-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - emptyDir: {} + name: helm-working-dir + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - emptyDir: {} + name: var-files + - emptyDir: {} + name: plugins +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + key: server.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + key: server.basehref + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + key: server.rootpath + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: server.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + key: server.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + key: server.dex.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + key: server.disable.auth + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + key: server.enable.gzip + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: server.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + key: server.x.frame.options + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + key: server.content.security.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.dex.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.dex.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: server.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.connection.status.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.oidc.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.login.attempts.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + key: server.staticassets + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + key: server.http.cookie.maxnumber + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + key: server.enable.proxy.extension + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-server + ports: + - containerPort: 8080 + - containerPort: 8083 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/server/tls + name: argocd-repo-server-tls + - mountPath: /app/config/dex/tls + name: argocd-dex-server-tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /tmp + name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-server + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + serviceName: argocd-application-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-application-controller + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-application-controller + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_CONTROLLER_REPLICAS + value: "1" + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.hard.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.status.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.operation.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: controller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: controller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.metrics.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: controller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: controller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + key: controller.resource.health.persist + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM + valueFrom: + configMapKeyRef: + key: controller.sharding.algorithm + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: controller.kubectl.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.ignore.normalizer.jq.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-application-controller + ports: + - containerPort: 8082 + readinessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp + workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-application-controller + volumes: + - emptyDir: {} + name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-application-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8082 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-applicationset-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 7000 + protocol: TCP + - port: 8080 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-commit-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 8086 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8087 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-dex-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + ports: + - port: 5556 + protocol: TCP + - port: 5557 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 5558 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 9001 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 6379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-repo-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + ports: + - port: 8081 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8084 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-server-network-policy +spec: + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + policyTypes: + - Ingress diff --git a/manifests/install.yaml b/manifests/install.yaml index 6fd35145cb0ca..61dfdd5759622 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -115,6 +115,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number of auto-heal + attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -304,6 +309,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -451,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -670,6 +687,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -819,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1151,6 +1180,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation step + (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1297,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1363,6 +1404,64 @@ spec: required: - repoURL type: object + sourceHydrator: + description: SourceHydrator provides a way to push hydrated manifests + back to git before syncing them to the cluster. + properties: + drySource: + description: DrySource specifies where the dry "don't repeat yourself" + manifest source lives. + properties: + path: + description: Path is a directory path within the Git repository + where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository that + contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated manifests + from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: description: Sources is a reference to the location of the application's manifests or chart @@ -1508,6 +1607,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema validation + (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -1655,6 +1762,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1833,6 +1944,11 @@ spec: description: Health contains information about the application's current health status properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus was + set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -2030,6 +2146,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2179,6 +2303,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2399,6 +2527,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -2550,6 +2686,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2710,6 +2850,11 @@ spec: sync: description: Sync contains parameters for the operation properties: + autoHealAttemptsCount: + description: SelfHealAttemptsCount contains the number + of auto-heal attempts + format: int64 + type: integer dryRun: description: DryRun specifies to perform a `kubectl apply --dry-run` without actually performing the sync @@ -2913,6 +3058,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3065,6 +3218,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3300,6 +3458,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON + schema validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3455,6 +3621,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -3804,6 +3975,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -3955,6 +4134,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4185,6 +4368,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4337,6 +4528,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4443,6 +4638,11 @@ spec: description: HealthStatus contains information about the currently observed health state of an application or resource properties: + lastTransitionTime: + description: LastTransitionTime is the time the HealthStatus + was set or updated + format: date-time + type: string message: description: Message is a human-readable informational message describing the health status @@ -4460,6 +4660,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4473,6 +4675,177 @@ spec: type: string type: object type: array + sourceHydrator: + description: SourceHydrator stores information about the current state + of source hydration + properties: + currentOperation: + description: CurrentOperation holds the status of the hydrate + operation + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + finishedAt: + description: FinishedAt indicates when the hydrate operation + finished + format: date-time + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + message: + description: Message contains a message describing the current + status of the hydrate operation + type: string + phase: + description: Phase indicates the status of the hydrate operation + enum: + - Hydrating + - Failed + - Hydrated + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + startedAt: + description: StartedAt indicates when the hydrate operation + started + format: date-time + type: string + required: + - message + - phase + type: object + lastSuccessfulOperation: + description: LastSuccessfulOperation holds info about the most + recent successful hydration + properties: + drySHA: + description: DrySHA holds the resolved revision (sha) of the + dry source as of the most recent reconciliation + type: string + hydratedSHA: + description: HydratedSHA holds the resolved revision (sha) + of the hydrated source as of the most recent reconciliation + type: string + sourceHydrator: + description: SourceHydrator holds the hydrator config used + for the hydrate operation + properties: + drySource: + description: DrySource specifies where the dry "don't + repeat yourself" manifest source lives. + properties: + path: + description: Path is a directory path within the Git + repository where the manifests are located + type: string + repoURL: + description: RepoURL is the URL to the git repository + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to hydrate + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + description: |- + HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + have to move manifests to the SyncSource, e.g. by pull request. + properties: + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - targetBranch + type: object + syncSource: + description: SyncSource specifies where to sync hydrated + manifests from. + properties: + path: + description: |- + Path is a directory path within the git repository where hydrated manifests should be committed to and synced + from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + type: string + targetBranch: + description: TargetBranch is the branch to which hydrated + manifests should be committed + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + type: object + type: object sourceType: description: SourceType specifies the type of this application type: string @@ -4710,6 +5083,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -4861,6 +5242,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5091,6 +5476,14 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) type: boolean + skipSchemaValidation: + description: SkipSchemaValidation skips JSON schema + validation (Helm's --skip-schema-validation) + type: boolean + skipTests: + description: SkipTests skips test manifest installation + step (Helm's --skip-tests). + type: boolean valueFiles: description: ValuesFiles is a list of Helm value files to use when generating a template @@ -5243,6 +5636,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5579,6 +5976,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5677,6 +6078,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5722,6 +6125,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -5809,6 +6248,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5907,6 +6350,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6013,6 +6458,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6648,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6299,6 +6750,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6344,6 +6797,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -6431,6 +6920,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6529,6 +7022,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6824,6 +7319,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6922,6 +7421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6967,6 +7468,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -7054,6 +7591,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7152,6 +7693,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7427,6 +7970,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7525,6 +8072,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7570,14 +8119,50 @@ spec: required: - repoURL type: object - sources: - items: - properties: - chart: - type: string - directory: - properties: - exclude: + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: type: string include: type: string @@ -7657,6 +8242,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7755,6 +8344,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8055,6 +8646,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8153,6 +8748,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8198,6 +8795,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8285,6 +8918,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8383,6 +9020,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8489,6 +9128,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +9318,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8775,6 +9420,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8820,6 +9467,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -8907,6 +9590,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9005,6 +9692,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9300,6 +9989,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9398,6 +10091,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9443,6 +10138,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -9530,6 +10261,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9628,6 +10363,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9903,6 +10640,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10001,6 +10742,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10046,6 +10789,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10133,6 +10912,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10231,6 +11014,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10514,6 +11299,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10612,6 +11401,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10657,6 +11448,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -10744,6 +11571,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10842,6 +11673,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11344,6 +12177,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11442,6 +12279,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11487,6 +12326,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -11574,6 +12449,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11672,6 +12551,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12169,6 +13050,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12267,6 +13152,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12312,6 +13199,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -12399,6 +13322,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12497,6 +13424,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12789,6 +13718,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12887,6 +13820,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12932,6 +13867,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13019,6 +13990,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13117,6 +14092,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13419,6 +14396,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13517,6 +14498,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13562,6 +14545,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -13649,6 +14668,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13747,6 +14770,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13853,6 +14878,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +15068,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14139,6 +15170,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14184,6 +15217,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14271,6 +15340,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14369,6 +15442,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14664,6 +15739,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14762,6 +15841,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14807,6 +15888,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -14894,6 +16011,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14992,6 +16113,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15267,6 +16390,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15365,6 +16492,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15410,6 +16539,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -15497,6 +16662,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15595,6 +16764,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15878,6 +17049,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15976,6 +17151,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16019,7 +17196,43 @@ spec: targetRevision: type: string required: - - repoURL + - repoURL + type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource type: object sources: items: @@ -16108,6 +17321,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16206,6 +17423,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16708,6 +17927,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16806,6 +18029,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16851,6 +18076,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -16938,6 +18199,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17036,6 +18301,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17533,6 +18800,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17631,6 +18902,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17676,6 +18949,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -17763,6 +19072,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17861,6 +19174,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18157,6 +19472,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18255,6 +19574,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18300,6 +19621,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18387,6 +19744,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18485,6 +19846,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18767,6 +20130,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18865,6 +20232,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18910,6 +20279,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -18997,6 +20402,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19095,6 +20504,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19597,6 +21008,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19695,6 +21110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19740,6 +21157,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -19827,6 +21280,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19925,6 +21382,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20422,6 +21881,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20520,6 +21983,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20565,6 +22030,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -20652,6 +22153,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20750,6 +22255,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21117,6 +22624,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21215,6 +22726,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21260,6 +22773,42 @@ spec: required: - repoURL type: object + sourceHydrator: + properties: + drySource: + properties: + path: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - path + - repoURL + - targetRevision + type: object + hydrateTo: + properties: + targetBranch: + type: string + required: + - targetBranch + type: object + syncSource: + properties: + path: + type: string + targetBranch: + type: string + required: + - path + - targetBranch + type: object + required: + - drySource + - syncSource + type: object sources: items: properties: @@ -21347,6 +22896,10 @@ spec: type: string skipCrds: type: boolean + skipSchemaValidation: + type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21445,6 +22998,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21604,6 +23159,9 @@ spec: type: string health: properties: + lastTransitionTime: + format: date-time + type: string message: type: string status: @@ -21617,6 +23175,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +23295,7 @@ spec: sync operation. properties: defaultServiceAccount: - description: ServiceAccountName to be used for impersonation + description: DefaultServiceAccount to be used for impersonation during the sync operation type: string namespace: @@ -21746,6 +23306,9 @@ spec: description: Server specifies the URL of the target cluster's Kubernetes control plane API. type: string + required: + - defaultServiceAccount + - server type: object type: array destinations: @@ -22958,6 +24521,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -23018,6 +24587,12 @@ spec: key: applicationsetcontroller.webhook.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -23048,6 +24623,8 @@ spec: name: tmp - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-applicationset-controller volumes: - configMap: @@ -23170,6 +24747,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -23259,6 +24838,8 @@ spec: - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls workingDir: /app + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true seccompProfile: @@ -23353,6 +24934,8 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 999 @@ -23522,6 +25105,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -23660,6 +25249,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -23998,6 +25589,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -24041,6 +25638,8 @@ spec: name: tmp - mountPath: /home/argocd/params name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -24198,6 +25797,30 @@ spec: key: controller.self.heal.timeout.seconds name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -24306,6 +25929,14 @@ spec: key: controller.ignore.normalizer.jq.timeout name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -24333,11 +25964,17 @@ spec: name: argocd-home - mountPath: /home/argocd/params name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-application-controller volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: items: diff --git a/manifests/namespace-install-with-hydrator.yaml b/manifests/namespace-install-with-hydrator.yaml new file mode 100644 index 0000000000000..ac43cc4f2da97 --- /dev/null +++ b/manifests/namespace-install-with-hydrator.yaml @@ -0,0 +1,2582 @@ +# This is an auto-generated file. DO NOT EDIT +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resourceNames: + - argocd-notifications-cm + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resourceNames: + - argocd-notifications-secret + resources: + - secrets + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +rules: +- apiGroups: + - "" + resourceNames: + - argocd-redis + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + - applicationsets + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-application-controller +subjects: +- kind: ServiceAccount + name: argocd-application-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-dex-server +subjects: +- kind: ServiceAccount + name: argocd-dex-server +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-notifications-controller +subjects: +- kind: ServiceAccount + name: argocd-notifications-controller +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-redis +subjects: +- kind: ServiceAccount + name: argocd-redis +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: argocd-server +subjects: +- kind: ServiceAccount + name: argocd-server +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cm + app.kubernetes.io/part-of: argocd + name: argocd-cm +--- +apiVersion: v1 +data: + hydrator.enabled: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-cmd-params-cm + app.kubernetes.io/part-of: argocd + name: argocd-cmd-params-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-gpg-keys-cm + app.kubernetes.io/part-of: argocd + name: argocd-gpg-keys-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-rbac-cm + app.kubernetes.io/part-of: argocd + name: argocd-rbac-cm +--- +apiVersion: v1 +data: + ssh_known_hosts: | + # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT + [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE= + bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-ssh-known-hosts-cm + app.kubernetes.io/part-of: argocd + name: argocd-ssh-known-hosts-cm +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/name: argocd-tls-certs-cm + app.kubernetes.io/part-of: argocd + name: argocd-tls-certs-cm +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-secret +type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/name: argocd-secret + app.kubernetes.io/part-of: argocd + name: argocd-secret +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + ports: + - name: webhook + port: 7000 + protocol: TCP + targetPort: webhook + - name: metrics + port: 8080 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/name: argocd-applicationset-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + ports: + - name: server + port: 8086 + protocol: TCP + targetPort: 8086 + - name: metrics + port: 8087 + protocol: TCP + targetPort: 8087 + selector: + app.kubernetes.io/name: argocd-commit-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + ports: + - appProtocol: TCP + name: http + port: 5556 + protocol: TCP + targetPort: 5556 + - name: grpc + port: 5557 + protocol: TCP + targetPort: 5557 + - name: metrics + port: 5558 + protocol: TCP + targetPort: 5558 + selector: + app.kubernetes.io/name: argocd-dex-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: metrics + app.kubernetes.io/name: argocd-metrics + app.kubernetes.io/part-of: argocd + name: argocd-metrics +spec: + ports: + - name: metrics + port: 8082 + protocol: TCP + targetPort: 8082 + selector: + app.kubernetes.io/name: argocd-application-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller-metrics + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-metrics +spec: + ports: + - name: metrics + port: 9001 + protocol: TCP + targetPort: 9001 + selector: + app.kubernetes.io/name: argocd-notifications-controller +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + ports: + - name: tcp-redis + port: 6379 + targetPort: 6379 + selector: + app.kubernetes.io/name: argocd-redis +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + ports: + - name: server + port: 8081 + protocol: TCP + targetPort: 8081 + - name: metrics + port: 8084 + protocol: TCP + targetPort: 8084 + selector: + app.kubernetes.io/name: argocd-repo-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8080 + - name: https + port: 443 + protocol: TCP + targetPort: 8080 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server-metrics + app.kubernetes.io/part-of: argocd + name: argocd-server-metrics +spec: + ports: + - name: metrics + port: 8083 + protocol: TCP + targetPort: 8083 + selector: + app.kubernetes.io/name: argocd-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-applicationset-controller + env: + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.annotations + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.global.preserved.labels + name: argocd-cmd-params-cm + optional: true + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.policy.override + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_CONCURRENT_RECONCILIATIONS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.concurrent.reconciliations.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-applicationset-controller + ports: + - containerPort: 7000 + name: webhook + - containerPort: 8080 + name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-applicationset-controller + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: commit-server + app.kubernetes.io/name: argocd-commit-server + app.kubernetes.io/part-of: argocd + name: argocd-commit-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-commit-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-commit-server + env: + - name: ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: commitserver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: commitserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_COMMIT_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: commitserver.log.level + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8087 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-commit-server + ports: + - containerPort: 8086 + - containerPort: 8087 + readinessProbe: + httpGet: + path: /healthz + port: 8087 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + serviceAccountName: argocd-commit-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - name: argocd-commit-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-commit-server-tls + - emptyDir: {} + name: var-files +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: dex-server + app.kubernetes.io/name: argocd-dex-server + app.kubernetes.io/part-of: argocd + name: argocd-dex-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-dex-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - command: + - /shared/argocd-dex + - rundex + env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: dexserver.disable.tls + name: argocd-cmd-params-cm + optional: true + image: ghcr.io/dexidp/dex:v2.41.1 + imagePullPolicy: Always + name: dex + ports: + - containerPort: 5556 + - containerPort: 5557 + - containerPort: 5558 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + - mountPath: /tls + name: argocd-dex-server-tls + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /shared/argocd-dex + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-dex-server + volumes: + - emptyDir: {} + name: static-files + - emptyDir: {} + name: dexconfig + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + strategy: + type: Recreate + template: + metadata: + labels: + app.kubernetes.io/name: argocd-notifications-controller + spec: + containers: + - args: + - /usr/local/bin/argocd-notifications + env: + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATIONS_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: notificationscontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + tcpSocket: + port: 9001 + name: argocd-notifications-controller + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + workingDir: /app + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-notifications-controller + volumes: + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: redis + app.kubernetes.io/name: argocd-redis + app.kubernetes.io/part-of: argocd + name: argocd-redis +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis + template: + metadata: + labels: + app.kubernetes.io/name: argocd-redis + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - --save + - "" + - --appendonly + - "no" + - --requirepass $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + image: redis:7.0.15-alpine + imagePullPolicy: Always + name: redis + ports: + - containerPort: 6379 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + initContainers: + - command: + - argocd + - admin + - redis-initial-password + image: quay.io/argoproj/argocd:latest + imagePullPolicy: IfNotPresent + name: secret-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + serviceAccountName: argocd-redis +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: repo-server + app.kubernetes.io/name: argocd-repo-server + app.kubernetes.io/part-of: argocd + name: argocd-repo-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-repo-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + automountServiceAccountToken: false + containers: + - args: + - /usr/local/bin/argocd-repo-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: reposerver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: reposerver.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_LISTEN_METRICS_ADDRESS + valueFrom: + configMapKeyRef: + key: reposerver.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + key: reposerver.disable.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: reposerver.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: reposerver.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.repo.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: reposerver.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.max.combined.directory.manifests.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.tar.exclusions + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.disable.helm.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.revision.cache.lock.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GRPC_MAX_SIZE_MB + valueFrom: + configMapKeyRef: + key: reposerver.grpc.max.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES + valueFrom: + configMapKeyRef: + key: reposerver.include.hidden.directories + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz?full=true + port: 8084 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-repo-server + ports: + - containerPort: 8081 + - containerPort: 8084 + readinessProbe: + httpGet: + path: /healthz + port: 8084 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /tmp + name: tmp + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + initContainers: + - command: + - /bin/cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: quay.io/argoproj/argocd:latest + name: copyutil + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-repo-server + volumes: + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - emptyDir: {} + name: helm-working-dir + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - emptyDir: {} + name: var-files + - emptyDir: {} + name: plugins +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: server + app.kubernetes.io/name: argocd-server + app.kubernetes.io/part-of: argocd + name: argocd-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-server + template: + metadata: + labels: + app.kubernetes.io/name: argocd-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + key: server.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + key: server.basehref + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + key: server.rootpath + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: server.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + key: server.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + key: server.dex.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + key: server.disable.auth + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + key: server.enable.gzip + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: server.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + key: server.x.frame.options + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + key: server.content.security.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: server.dex.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: server.dex.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.minversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + key: server.tls.maxversion + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + key: server.tls.ciphers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.connection.status.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.oidc.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.login.attempts.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + key: server.staticassets + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: server.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + key: server.http.cookie.maxnumber + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + key: server.metrics.listen.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + key: server.enable.proxy.extension + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + name: argocd-server + ports: + - containerPort: 8080 + - containerPort: 8083 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/server/tls + name: argocd-repo-server-tls + - mountPath: /app/config/dex/tls + name: argocd-dex-server-tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /tmp + name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-server + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp + - configMap: + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + name: argocd-tls-certs-cm + name: tls-certs + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - name: argocd-dex-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: application-controller + app.kubernetes.io/name: argocd-application-controller + app.kubernetes.io/part-of: argocd + name: argocd-application-controller +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + serviceName: argocd-application-controller + template: + metadata: + labels: + app.kubernetes.io/name: argocd-application-controller + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + topologyKey: kubernetes.io/hostname + weight: 100 + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname + weight: 5 + containers: + - args: + - /usr/local/bin/argocd-application-controller + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_CONTROLLER_REPLICAS + value: "1" + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + key: timeout.hard.reconciliation + name: argocd-cm + optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.server.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.status.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + key: controller.operation.processors + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: controller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: controller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.metrics.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: controller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + key: controller.repo.server.strict.tls + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + key: controller.resource.health.persist + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.app.state.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + key: redis.server + name: argocd-cmd-params-cm + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + key: redis.compression + name: argocd-cmd-params-cm + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + key: redis.db + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + key: controller.default.cache.expiration + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + key: otlp.address + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + key: application.namespaces + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM + valueFrom: + configMapKeyRef: + key: controller.sharding.algorithm + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: controller.kubectl.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.ignore.normalizer.jq.timeout + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + name: argocd-application-controller + ports: + - containerPort: 8082 + readinessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp + workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: argocd-application-controller + volumes: + - emptyDir: {} + name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp + - name: argocd-repo-server-tls + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + optional: true + secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-application-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8082 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-applicationset-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 7000 + protocol: TCP + - port: 8080 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-commit-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 8086 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8087 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-commit-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-dex-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + ports: + - port: 5556 + protocol: TCP + - port: 5557 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 5558 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/component: notifications-controller + app.kubernetes.io/name: argocd-notifications-controller + app.kubernetes.io/part-of: argocd + name: argocd-notifications-controller-network-policy +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 9001 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-redis-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + ports: + - port: 6379 + protocol: TCP + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-redis + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-repo-server-network-policy +spec: + ingress: + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-application-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller + - podSelector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + ports: + - port: 8081 + protocol: TCP + - from: + - namespaceSelector: {} + ports: + - port: 8084 + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-repo-server + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: argocd-server-network-policy +spec: + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + policyTypes: + - Ingress diff --git a/manifests/namespace-install-with-hydrator/kustomization.yaml b/manifests/namespace-install-with-hydrator/kustomization.yaml new file mode 100644 index 0000000000000..dd1e18e1d0bab --- /dev/null +++ b/manifests/namespace-install-with-hydrator/kustomization.yaml @@ -0,0 +1,12 @@ +resources: + - ../namespace-install + - ../base/commit-server + +patches: + - target: + kind: ConfigMap + name: argocd-cmd-params-cm + patch: |- + - op: add + path: /data + value: {"hydrator.enabled": "true"} diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 0d9c0816cfe30..3c6e616fe0fdb 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -751,6 +751,12 @@ spec: key: applicationsetcontroller.enable.progressive.syncs name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_TOKENREF_STRICT_MODE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.tokenref.strict.mode + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING valueFrom: configMapKeyRef: @@ -811,6 +817,12 @@ spec: key: applicationsetcontroller.webhook.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REQUEUE_AFTER + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.requeue.after + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -841,6 +853,8 @@ spec: name: tmp - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-applicationset-controller volumes: - configMap: @@ -963,6 +977,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -1052,6 +1068,8 @@ spec: - mountPath: /app/config/reposerver/tls name: argocd-repo-server-tls workingDir: /app + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true seccompProfile: @@ -1146,6 +1164,8 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 999 @@ -1315,6 +1335,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -1453,6 +1479,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -1791,6 +1819,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -1834,6 +1868,8 @@ spec: name: tmp - mountPath: /home/argocd/params name: argocd-cmd-params-cm + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -1991,6 +2027,30 @@ spec: key: controller.self.heal.timeout.seconds name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.timeout.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.factor + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS + valueFrom: + configMapKeyRef: + key: controller.self.heal.backoff.cap.seconds + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT + valueFrom: + configMapKeyRef: + key: controller.sync.timeout.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -2099,6 +2159,14 @@ spec: key: controller.ignore.normalizer.jq.timeout name: argocd-cmd-params-cm optional: true + - name: ARGOCD_HYDRATOR_ENABLED + valueFrom: + configMapKeyRef: + key: hydrator.enabled + name: argocd-cmd-params-cm + optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -2126,11 +2194,17 @@ spec: name: argocd-home - mountPath: /home/argocd/params name: argocd-cmd-params-cm + - mountPath: /tmp + name: argocd-application-controller-tmp workingDir: /home/argocd + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-application-controller volumes: - emptyDir: {} name: argocd-home + - emptyDir: {} + name: argocd-application-controller-tmp - name: argocd-repo-server-tls secret: items: diff --git a/mkdocs.yml b/mkdocs.yml index 1fea9734a8710..d2d59fdd6b0e8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -23,6 +23,7 @@ nav: - operator-manual/index.md - operator-manual/architecture.md - operator-manual/installation.md + - operator-manual/feature-maturity.md - operator-manual/core.md - operator-manual/declarative-setup.md - operator-manual/app-any-namespace.md diff --git a/notifications_catalog/install.yaml b/notifications_catalog/install.yaml index 7457b25ddad89..25aebf826e3d4 100644 --- a/notifications_catalog/install.yaml +++ b/notifications_catalog/install.yaml @@ -30,8 +30,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true }, { @@ -59,8 +59,8 @@ data: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }, { "name": "Revision", @@ -74,7 +74,7 @@ data: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Operation Application", @@ -88,7 +88,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#000080' @@ -112,8 +112,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -136,8 +136,8 @@ data: "value": "{{.app.status.health.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -161,7 +161,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#FF0000' @@ -185,8 +185,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -213,8 +213,8 @@ data: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -224,7 +224,7 @@ data: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Operation", @@ -238,7 +238,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#FF0000' @@ -262,8 +262,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -290,8 +290,8 @@ data: "value": "{{.app.status.operationState.startedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -301,7 +301,7 @@ data: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Operation", @@ -315,7 +315,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] title: Start syncing application {{.app.metadata.name}}. @@ -343,8 +343,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -367,8 +367,8 @@ data: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -378,7 +378,7 @@ data: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Open Application", @@ -392,7 +392,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] title: Application {{.app.metadata.name}} sync status is 'Unknown' @@ -415,8 +415,8 @@ data: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -443,8 +443,8 @@ data: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -454,7 +454,7 @@ data: } {{end}} ] - potentialAction: |- + potentialAction: | [{ "@type":"OpenUri", "name":"Operation Details", @@ -468,7 +468,7 @@ data: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] themeColor: '#000080' diff --git a/notifications_catalog/templates/app-deployed.yaml b/notifications_catalog/templates/app-deployed.yaml index ee58c775f1fd8..8e55db33e5b42 100644 --- a/notifications_catalog/templates/app-deployed.yaml +++ b/notifications_catalog/templates/app-deployed.yaml @@ -15,8 +15,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true }, { @@ -43,8 +43,8 @@ teams: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }, { "name": "Revision", @@ -72,6 +72,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] - }] \ No newline at end of file + }] diff --git a/notifications_catalog/templates/app-health-degraded.yaml b/notifications_catalog/templates/app-health-degraded.yaml index 59115c9a14935..1737bfa97ea14 100644 --- a/notifications_catalog/templates/app-health-degraded.yaml +++ b/notifications_catalog/templates/app-health-degraded.yaml @@ -16,8 +16,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -39,8 +39,8 @@ teams: "value": "{{.app.status.health.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -64,6 +64,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] }] diff --git a/notifications_catalog/templates/app-sync-failed.yaml b/notifications_catalog/templates/app-sync-failed.yaml index a4c23787dde8b..509aacd365675 100644 --- a/notifications_catalog/templates/app-sync-failed.yaml +++ b/notifications_catalog/templates/app-sync-failed.yaml @@ -16,8 +16,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -43,8 +43,8 @@ teams: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -68,6 +68,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] - }] \ No newline at end of file + }] diff --git a/notifications_catalog/templates/app-sync-running.yaml b/notifications_catalog/templates/app-sync-running.yaml index 434132ad86d89..55dc9f9b1091b 100644 --- a/notifications_catalog/templates/app-sync-running.yaml +++ b/notifications_catalog/templates/app-sync-running.yaml @@ -16,8 +16,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -42,8 +42,8 @@ teams: "value": "{{.app.status.operationState.startedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -67,6 +67,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] - }] \ No newline at end of file + }] diff --git a/notifications_catalog/templates/app-sync-status-unknown.yaml b/notifications_catalog/templates/app-sync-status-unknown.yaml index c893070bfcc63..69d3e22363d9a 100644 --- a/notifications_catalog/templates/app-sync-status-unknown.yaml +++ b/notifications_catalog/templates/app-sync-status-unknown.yaml @@ -21,8 +21,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -43,8 +43,8 @@ teams: "value": "{{.app.status.sync.status}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -68,6 +68,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] - }] \ No newline at end of file + }] diff --git a/notifications_catalog/templates/app-sync-succeeded.yaml b/notifications_catalog/templates/app-sync-succeeded.yaml index 76e467bd1c37d..2f88860f18391 100644 --- a/notifications_catalog/templates/app-sync-succeeded.yaml +++ b/notifications_catalog/templates/app-sync-succeeded.yaml @@ -16,8 +16,8 @@ slack: "short": true }, { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", + "title": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, "short": true } {{range $index, $c := .app.status.conditions}} @@ -43,8 +43,8 @@ teams: "value": "{{.app.status.operationState.finishedAt}}" }, { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" + "name": {{- if .app.spec.source }} "Repository" {{- else if .app.spec.sources }} "Repositories" {{- end }}, + "value": {{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, } {{range $index, $c := .app.status.conditions}} , @@ -68,6 +68,6 @@ teams: "name":"Open Repository", "targets":[{ "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + "uri":{{- if .app.spec.source }} ":arrow_heading_up: {{ .app.spec.source.repoURL }}" {{- else if .app.spec.sources }} "{{- range $index, $source := .app.spec.sources }}{{ if $index }}\n{{ end }}:arrow_heading_up: {{ $source.repoURL }}{{- end }}" {{- end }}, }] - }] \ No newline at end of file + }] diff --git a/pkg/apiclient/apiclient.go b/pkg/apiclient/apiclient.go index 52164255164ae..b0c8f83bc6362 100644 --- a/pkg/apiclient/apiclient.go +++ b/pkg/apiclient/apiclient.go @@ -126,6 +126,7 @@ type ClientOptions struct { RedisHaProxyName string RedisName string RepoServerName string + PromptsEnabled bool } type client struct { diff --git a/pkg/apiclient/repocreds/repocreds.pb.go b/pkg/apiclient/repocreds/repocreds.pb.go index 132f2d23c9e68..6a856e869f126 100644 --- a/pkg/apiclient/repocreds/repocreds.pb.go +++ b/pkg/apiclient/repocreds/repocreds.pb.go @@ -285,38 +285,43 @@ func init() { func init() { proto.RegisterFile("server/repocreds/repocreds.proto", fileDescriptor_b0b5fce4710a8821) } var fileDescriptor_b0b5fce4710a8821 = []byte{ - // 481 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0xc1, 0x6a, 0x14, 0x31, - 0x18, 0xc7, 0x49, 0xa5, 0xc5, 0x46, 0x90, 0x76, 0x0a, 0xb5, 0x3b, 0x5b, 0xd7, 0x35, 0x07, 0x29, - 0x45, 0x13, 0x76, 0x05, 0x0f, 0x1e, 0x6d, 0xc1, 0x83, 0xbd, 0x38, 0xe2, 0x45, 0x10, 0x49, 0x67, - 0x3e, 0xa6, 0xb1, 0x71, 0x12, 0x93, 0xcc, 0x48, 0x11, 0x11, 0x7c, 0x01, 0x0f, 0x5e, 0xc5, 0x17, - 0xf0, 0x01, 0x7c, 0x05, 0x8f, 0x82, 0x2f, 0x20, 0x8b, 0x0f, 0x22, 0xc9, 0xee, 0xcc, 0xec, 0xd2, - 0x39, 0xec, 0x61, 0xf1, 0xf6, 0x4d, 0xf2, 0xe5, 0x9f, 0xdf, 0x7f, 0xbe, 0xef, 0x0b, 0x1e, 0x5a, - 0x30, 0x15, 0x18, 0x66, 0x40, 0xab, 0xd4, 0x40, 0x66, 0xdb, 0x88, 0x6a, 0xa3, 0x9c, 0x8a, 0x36, - 0x9b, 0x85, 0x78, 0x3f, 0x57, 0x2a, 0x97, 0xc0, 0xb8, 0x16, 0x8c, 0x17, 0x85, 0x72, 0xdc, 0x09, - 0x55, 0xcc, 0x12, 0xe3, 0x93, 0x5c, 0xb8, 0xb3, 0xf2, 0x94, 0xa6, 0xea, 0x0d, 0xe3, 0x26, 0x57, - 0xda, 0xa8, 0xd7, 0x21, 0xb8, 0x97, 0x66, 0xac, 0x1a, 0x33, 0x7d, 0x9e, 0xfb, 0x93, 0x96, 0x71, - 0xad, 0xa5, 0x48, 0xc3, 0x59, 0x56, 0x8d, 0xb8, 0xd4, 0x67, 0x7c, 0xc4, 0x72, 0x28, 0xc0, 0x70, - 0x07, 0xd9, 0x54, 0x8d, 0x10, 0x7c, 0x3d, 0x01, 0xad, 0x8e, 0xfc, 0xc5, 0x4f, 0x4b, 0x30, 0x17, - 0xd1, 0x16, 0xbe, 0x52, 0x1a, 0xb9, 0x87, 0x86, 0xe8, 0x60, 0x33, 0xf1, 0x21, 0x39, 0xc4, 0xbb, - 0x4d, 0xce, 0x31, 0x48, 0x70, 0x90, 0xc0, 0xdb, 0x12, 0xac, 0xeb, 0xc8, 0xdd, 0xc1, 0xdb, 0x4d, - 0x6e, 0x02, 0x56, 0xab, 0xc2, 0x02, 0xf9, 0x8c, 0xe6, 0x14, 0x8e, 0x0c, 0xf0, 0x56, 0xe1, 0x25, - 0x5e, 0x0f, 0xa6, 0x83, 0xc6, 0xb5, 0xf1, 0x63, 0xda, 0xba, 0xa3, 0xb5, 0xbb, 0x10, 0xbc, 0x4a, - 0x33, 0x5a, 0x8d, 0xa9, 0x3e, 0xcf, 0xa9, 0x77, 0x47, 0xe7, 0xdc, 0xd1, 0xda, 0x1d, 0x6d, 0xaf, - 0x9e, 0xaa, 0x46, 0xbb, 0x78, 0xa3, 0xd4, 0x16, 0x8c, 0xdb, 0x5b, 0x1b, 0xa2, 0x83, 0xab, 0xc9, - 0xec, 0x8b, 0xbc, 0x9b, 0x03, 0x7a, 0xae, 0xb3, 0xff, 0x06, 0x34, 0xfe, 0xba, 0x8e, 0xb7, 0x9a, - 0xc5, 0x67, 0x60, 0x2a, 0x91, 0x42, 0xf4, 0x0d, 0xe1, 0xde, 0x89, 0xb0, 0xce, 0x6f, 0x58, 0xe1, - 0x94, 0xb9, 0xf0, 0xdb, 0x50, 0x38, 0xc1, 0xa5, 0x8d, 0x7a, 0xb4, 0xed, 0x95, 0xc5, 0x5a, 0xc5, - 0x4f, 0x56, 0x44, 0xe7, 0x2f, 0x27, 0xbd, 0x4f, 0xbf, 0xff, 0x7e, 0x59, 0xdb, 0x89, 0xb6, 0x43, - 0xe3, 0x55, 0xa3, 0xb6, 0x45, 0xa3, 0xef, 0x08, 0xf7, 0xeb, 0xba, 0x75, 0x21, 0xde, 0xee, 0x42, - 0x5c, 0x28, 0x74, 0xbc, 0xaa, 0x1f, 0x49, 0x86, 0x01, 0x33, 0x26, 0x97, 0x31, 0x1f, 0xce, 0x8a, - 0xfe, 0x03, 0xe1, 0x7e, 0x5d, 0xd4, 0xa5, 0x69, 0x17, 0xba, 0x60, 0x75, 0xb4, 0x77, 0x03, 0xed, - 0x9d, 0xf8, 0xe6, 0x25, 0x5a, 0xf6, 0x7e, 0x4a, 0x50, 0x1a, 0xf9, 0xa1, 0x26, 0xff, 0x88, 0xfb, - 0xf5, 0x80, 0x2d, 0x0d, 0xbe, 0x30, 0x91, 0xf1, 0x7e, 0x57, 0x4a, 0x33, 0x88, 0xb7, 0x02, 0x4d, - 0xef, 0xf0, 0x46, 0x07, 0x8d, 0xe7, 0x78, 0x74, 0xfc, 0x73, 0x32, 0x40, 0xbf, 0x26, 0x03, 0xf4, - 0x67, 0x32, 0x40, 0x2f, 0x1e, 0x2c, 0xf7, 0xd4, 0xa4, 0x52, 0x40, 0xe1, 0x5a, 0xad, 0xd3, 0x8d, - 0xf0, 0xb6, 0xdc, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x10, 0xaa, 0x0b, 0x07, 0xf6, 0x04, 0x00, - 0x00, + // 570 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0x41, 0x6b, 0xd4, 0x40, + 0x14, 0xc7, 0x99, 0x8a, 0xc5, 0x8e, 0x20, 0x6d, 0x0a, 0x6d, 0x37, 0xdb, 0x6e, 0x63, 0xc4, 0x52, + 0x96, 0x76, 0xc2, 0xae, 0xe0, 0xc1, 0xa3, 0x2d, 0x78, 0xb0, 0x17, 0x57, 0x44, 0x10, 0x44, 0xa6, + 0xd9, 0x47, 0x3a, 0x36, 0x66, 0xc6, 0x99, 0x49, 0x4a, 0x11, 0x11, 0x3c, 0x7a, 0xf1, 0xe0, 0xdd, + 0xbb, 0x78, 0xd7, 0xbb, 0x27, 0x8f, 0x42, 0xbf, 0x80, 0x2c, 0x7e, 0x10, 0x99, 0xc9, 0x66, 0xb3, + 0x4b, 0xb3, 0xb2, 0x0b, 0x6b, 0x7b, 0x7b, 0x49, 0x5e, 0xde, 0xfb, 0xfd, 0xff, 0xf3, 0x66, 0x06, + 0x7b, 0x0a, 0x64, 0x06, 0x32, 0x90, 0x20, 0x78, 0x28, 0xa1, 0xab, 0xca, 0x88, 0x08, 0xc9, 0x35, + 0x77, 0x16, 0x06, 0x2f, 0xdc, 0xf5, 0x88, 0xf3, 0x28, 0x86, 0x80, 0x0a, 0x16, 0xd0, 0x24, 0xe1, + 0x9a, 0x6a, 0xc6, 0x93, 0x7e, 0xa2, 0x7b, 0x10, 0x31, 0x7d, 0x94, 0x1e, 0x92, 0x90, 0xbf, 0x0a, + 0xa8, 0x8c, 0xb8, 0x90, 0xfc, 0xa5, 0x0d, 0x76, 0xc3, 0x6e, 0x90, 0xb5, 0x03, 0x71, 0x1c, 0x99, + 0x3f, 0x55, 0x40, 0x85, 0x88, 0x59, 0x68, 0xff, 0x0d, 0xb2, 0x16, 0x8d, 0xc5, 0x11, 0x6d, 0x05, + 0x11, 0x24, 0x20, 0xa9, 0x86, 0x6e, 0x5e, 0xcd, 0xf7, 0xf1, 0x8d, 0x0e, 0x08, 0xbe, 0x67, 0x1a, + 0x3f, 0x4a, 0x41, 0x9e, 0x3a, 0x8b, 0xf8, 0x4a, 0x2a, 0xe3, 0x35, 0xe4, 0xa1, 0xed, 0x85, 0x8e, + 0x09, 0xfd, 0x26, 0x5e, 0x19, 0xe4, 0xec, 0x43, 0x0c, 0x1a, 0x3a, 0xf0, 0x3a, 0x05, 0xa5, 0x2b, + 0x72, 0x97, 0xf1, 0xd2, 0x20, 0xb7, 0x03, 0x4a, 0xf0, 0x44, 0x81, 0xff, 0x11, 0x0d, 0x55, 0xd8, + 0x93, 0x40, 0xcb, 0x0a, 0xcf, 0xf1, 0x55, 0x2b, 0xda, 0xd6, 0xb8, 0xde, 0x7e, 0x40, 0x4a, 0x75, + 0xa4, 0x50, 0x67, 0x83, 0x17, 0x61, 0x97, 0x64, 0x6d, 0x22, 0x8e, 0x23, 0x62, 0xd4, 0x91, 0x21, + 0x75, 0xa4, 0x50, 0x47, 0xca, 0xd6, 0x79, 0x55, 0x67, 0x05, 0xcf, 0xa7, 0x42, 0x81, 0xd4, 0x6b, + 0x73, 0x1e, 0xda, 0xbe, 0xd6, 0xe9, 0x3f, 0xf9, 0x27, 0x43, 0x40, 0x4f, 0x44, 0xf7, 0xc2, 0x80, + 0xda, 0x67, 0x18, 0x2f, 0x0e, 0x5e, 0x3e, 0x06, 0x99, 0xb1, 0x10, 0x9c, 0xcf, 0x08, 0xd7, 0x0e, + 0x98, 0xd2, 0xe6, 0x83, 0x62, 0x9a, 0xcb, 0x53, 0xf3, 0x19, 0x12, 0xcd, 0x68, 0xac, 0x9c, 0x1a, + 0x29, 0x67, 0x65, 0x74, 0xad, 0xdc, 0x87, 0x33, 0xa2, 0x33, 0xcd, 0xfd, 0xda, 0xfb, 0xb3, 0x3f, + 0x9f, 0xe6, 0x96, 0x9d, 0x25, 0x3b, 0x78, 0x59, 0xab, 0x1c, 0x51, 0xe7, 0x0b, 0xc2, 0x0d, 0x93, + 0xf3, 0x54, 0x32, 0xe3, 0xd4, 0x65, 0x52, 0x6e, 0x5a, 0xca, 0x9a, 0xb3, 0x5a, 0x50, 0x9e, 0x18, + 0xa6, 0xdd, 0x92, 0xf5, 0x2b, 0xc2, 0xf5, 0x62, 0xc6, 0xaa, 0x40, 0x6f, 0x56, 0x81, 0x8e, 0x0c, + 0xa5, 0x3b, 0xab, 0x45, 0xf7, 0x3d, 0x0b, 0xeb, 0xfa, 0xe7, 0x2d, 0xbd, 0xd7, 0x1f, 0xd0, 0x6f, + 0x08, 0x7b, 0x79, 0xf3, 0x7f, 0x78, 0x7b, 0x91, 0xc8, 0x5b, 0x16, 0xd9, 0xf3, 0xc7, 0xf9, 0x5b, + 0x80, 0x7f, 0x47, 0xb8, 0x5e, 0xec, 0x9c, 0x89, 0x99, 0x47, 0xb6, 0xda, 0xec, 0x98, 0x77, 0x2c, + 0xf3, 0x96, 0xbb, 0x71, 0xce, 0xe6, 0xe0, 0x4d, 0x4e, 0x90, 0xca, 0xf8, 0x6d, 0x41, 0xfe, 0x03, + 0x61, 0x2f, 0x07, 0x99, 0xd6, 0xf2, 0xff, 0x84, 0xdf, 0xb6, 0xf8, 0x3b, 0xee, 0xad, 0x31, 0x96, + 0x57, 0x89, 0x78, 0x87, 0xeb, 0xc5, 0x51, 0x3c, 0x31, 0xfe, 0xc8, 0xd9, 0xed, 0xae, 0x57, 0xa5, + 0x0c, 0x8e, 0xec, 0xfe, 0x36, 0x6b, 0xae, 0x56, 0x58, 0x6a, 0x38, 0x9c, 0x0f, 0x08, 0x7b, 0x79, + 0xc1, 0x69, 0x5d, 0x9c, 0x06, 0xe3, 0xb6, 0xc5, 0xd8, 0x6c, 0x6e, 0x8c, 0xb5, 0xc6, 0xc0, 0xdc, + 0xdf, 0xff, 0xd9, 0x6b, 0xa0, 0x5f, 0xbd, 0x06, 0xfa, 0xdd, 0x6b, 0xa0, 0x67, 0x77, 0x27, 0xbb, + 0x21, 0xc3, 0x98, 0x41, 0xa2, 0x4b, 0x61, 0x87, 0xf3, 0xf6, 0x4a, 0xbc, 0xf3, 0x37, 0x00, 0x00, + 0xff, 0xff, 0xe4, 0x00, 0xe9, 0x59, 0xad, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -333,12 +338,20 @@ const _ = grpc.SupportPackageIsVersion4 type RepoCredsServiceClient interface { // ListRepositoryCredentials gets a list of all configured repository credential sets ListRepositoryCredentials(ctx context.Context, in *RepoCredsQuery, opts ...grpc.CallOption) (*v1alpha1.RepoCredsList, error) + //ListWriteRepositoryCredentials gets a list of all configured repository credential sets that have write access + ListWriteRepositoryCredentials(ctx context.Context, in *RepoCredsQuery, opts ...grpc.CallOption) (*v1alpha1.RepoCredsList, error) // CreateRepositoryCredentials creates a new repository credential set CreateRepositoryCredentials(ctx context.Context, in *RepoCredsCreateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) + // CreateWriteRepositoryCredentials creates a new repository credential set with write access + CreateWriteRepositoryCredentials(ctx context.Context, in *RepoCredsCreateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) // UpdateRepositoryCredentials updates a repository credential set UpdateRepositoryCredentials(ctx context.Context, in *RepoCredsUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) + // UpdateWriteRepositoryCredentials updates a repository credential set with write access + UpdateWriteRepositoryCredentials(ctx context.Context, in *RepoCredsUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) // DeleteRepositoryCredentials deletes a repository credential set from the configuration DeleteRepositoryCredentials(ctx context.Context, in *RepoCredsDeleteRequest, opts ...grpc.CallOption) (*RepoCredsResponse, error) + // DeleteWriteRepositoryCredentials deletes a repository credential set with write access from the configuration + DeleteWriteRepositoryCredentials(ctx context.Context, in *RepoCredsDeleteRequest, opts ...grpc.CallOption) (*RepoCredsResponse, error) } type repoCredsServiceClient struct { @@ -358,6 +371,15 @@ func (c *repoCredsServiceClient) ListRepositoryCredentials(ctx context.Context, return out, nil } +func (c *repoCredsServiceClient) ListWriteRepositoryCredentials(ctx context.Context, in *RepoCredsQuery, opts ...grpc.CallOption) (*v1alpha1.RepoCredsList, error) { + out := new(v1alpha1.RepoCredsList) + err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/ListWriteRepositoryCredentials", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repoCredsServiceClient) CreateRepositoryCredentials(ctx context.Context, in *RepoCredsCreateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) { out := new(v1alpha1.RepoCreds) err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/CreateRepositoryCredentials", in, out, opts...) @@ -367,6 +389,15 @@ func (c *repoCredsServiceClient) CreateRepositoryCredentials(ctx context.Context return out, nil } +func (c *repoCredsServiceClient) CreateWriteRepositoryCredentials(ctx context.Context, in *RepoCredsCreateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) { + out := new(v1alpha1.RepoCreds) + err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/CreateWriteRepositoryCredentials", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repoCredsServiceClient) UpdateRepositoryCredentials(ctx context.Context, in *RepoCredsUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) { out := new(v1alpha1.RepoCreds) err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/UpdateRepositoryCredentials", in, out, opts...) @@ -376,6 +407,15 @@ func (c *repoCredsServiceClient) UpdateRepositoryCredentials(ctx context.Context return out, nil } +func (c *repoCredsServiceClient) UpdateWriteRepositoryCredentials(ctx context.Context, in *RepoCredsUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.RepoCreds, error) { + out := new(v1alpha1.RepoCreds) + err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/UpdateWriteRepositoryCredentials", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repoCredsServiceClient) DeleteRepositoryCredentials(ctx context.Context, in *RepoCredsDeleteRequest, opts ...grpc.CallOption) (*RepoCredsResponse, error) { out := new(RepoCredsResponse) err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/DeleteRepositoryCredentials", in, out, opts...) @@ -385,16 +425,33 @@ func (c *repoCredsServiceClient) DeleteRepositoryCredentials(ctx context.Context return out, nil } +func (c *repoCredsServiceClient) DeleteWriteRepositoryCredentials(ctx context.Context, in *RepoCredsDeleteRequest, opts ...grpc.CallOption) (*RepoCredsResponse, error) { + out := new(RepoCredsResponse) + err := c.cc.Invoke(ctx, "/repocreds.RepoCredsService/DeleteWriteRepositoryCredentials", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RepoCredsServiceServer is the server API for RepoCredsService service. type RepoCredsServiceServer interface { // ListRepositoryCredentials gets a list of all configured repository credential sets ListRepositoryCredentials(context.Context, *RepoCredsQuery) (*v1alpha1.RepoCredsList, error) + //ListWriteRepositoryCredentials gets a list of all configured repository credential sets that have write access + ListWriteRepositoryCredentials(context.Context, *RepoCredsQuery) (*v1alpha1.RepoCredsList, error) // CreateRepositoryCredentials creates a new repository credential set CreateRepositoryCredentials(context.Context, *RepoCredsCreateRequest) (*v1alpha1.RepoCreds, error) + // CreateWriteRepositoryCredentials creates a new repository credential set with write access + CreateWriteRepositoryCredentials(context.Context, *RepoCredsCreateRequest) (*v1alpha1.RepoCreds, error) // UpdateRepositoryCredentials updates a repository credential set UpdateRepositoryCredentials(context.Context, *RepoCredsUpdateRequest) (*v1alpha1.RepoCreds, error) + // UpdateWriteRepositoryCredentials updates a repository credential set with write access + UpdateWriteRepositoryCredentials(context.Context, *RepoCredsUpdateRequest) (*v1alpha1.RepoCreds, error) // DeleteRepositoryCredentials deletes a repository credential set from the configuration DeleteRepositoryCredentials(context.Context, *RepoCredsDeleteRequest) (*RepoCredsResponse, error) + // DeleteWriteRepositoryCredentials deletes a repository credential set with write access from the configuration + DeleteWriteRepositoryCredentials(context.Context, *RepoCredsDeleteRequest) (*RepoCredsResponse, error) } // UnimplementedRepoCredsServiceServer can be embedded to have forward compatible implementations. @@ -404,15 +461,27 @@ type UnimplementedRepoCredsServiceServer struct { func (*UnimplementedRepoCredsServiceServer) ListRepositoryCredentials(ctx context.Context, req *RepoCredsQuery) (*v1alpha1.RepoCredsList, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRepositoryCredentials not implemented") } +func (*UnimplementedRepoCredsServiceServer) ListWriteRepositoryCredentials(ctx context.Context, req *RepoCredsQuery) (*v1alpha1.RepoCredsList, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWriteRepositoryCredentials not implemented") +} func (*UnimplementedRepoCredsServiceServer) CreateRepositoryCredentials(ctx context.Context, req *RepoCredsCreateRequest) (*v1alpha1.RepoCreds, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateRepositoryCredentials not implemented") } +func (*UnimplementedRepoCredsServiceServer) CreateWriteRepositoryCredentials(ctx context.Context, req *RepoCredsCreateRequest) (*v1alpha1.RepoCreds, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateWriteRepositoryCredentials not implemented") +} func (*UnimplementedRepoCredsServiceServer) UpdateRepositoryCredentials(ctx context.Context, req *RepoCredsUpdateRequest) (*v1alpha1.RepoCreds, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRepositoryCredentials not implemented") } +func (*UnimplementedRepoCredsServiceServer) UpdateWriteRepositoryCredentials(ctx context.Context, req *RepoCredsUpdateRequest) (*v1alpha1.RepoCreds, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateWriteRepositoryCredentials not implemented") +} func (*UnimplementedRepoCredsServiceServer) DeleteRepositoryCredentials(ctx context.Context, req *RepoCredsDeleteRequest) (*RepoCredsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteRepositoryCredentials not implemented") } +func (*UnimplementedRepoCredsServiceServer) DeleteWriteRepositoryCredentials(ctx context.Context, req *RepoCredsDeleteRequest) (*RepoCredsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteWriteRepositoryCredentials not implemented") +} func RegisterRepoCredsServiceServer(s *grpc.Server, srv RepoCredsServiceServer) { s.RegisterService(&_RepoCredsService_serviceDesc, srv) @@ -436,6 +505,24 @@ func _RepoCredsService_ListRepositoryCredentials_Handler(srv interface{}, ctx co return interceptor(ctx, in, info, handler) } +func _RepoCredsService_ListWriteRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoCredsQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepoCredsServiceServer).ListWriteRepositoryCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repocreds.RepoCredsService/ListWriteRepositoryCredentials", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepoCredsServiceServer).ListWriteRepositoryCredentials(ctx, req.(*RepoCredsQuery)) + } + return interceptor(ctx, in, info, handler) +} + func _RepoCredsService_CreateRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoCredsCreateRequest) if err := dec(in); err != nil { @@ -454,6 +541,24 @@ func _RepoCredsService_CreateRepositoryCredentials_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _RepoCredsService_CreateWriteRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoCredsCreateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepoCredsServiceServer).CreateWriteRepositoryCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repocreds.RepoCredsService/CreateWriteRepositoryCredentials", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepoCredsServiceServer).CreateWriteRepositoryCredentials(ctx, req.(*RepoCredsCreateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RepoCredsService_UpdateRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoCredsUpdateRequest) if err := dec(in); err != nil { @@ -472,6 +577,24 @@ func _RepoCredsService_UpdateRepositoryCredentials_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _RepoCredsService_UpdateWriteRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoCredsUpdateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepoCredsServiceServer).UpdateWriteRepositoryCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repocreds.RepoCredsService/UpdateWriteRepositoryCredentials", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepoCredsServiceServer).UpdateWriteRepositoryCredentials(ctx, req.(*RepoCredsUpdateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RepoCredsService_DeleteRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoCredsDeleteRequest) if err := dec(in); err != nil { @@ -490,6 +613,24 @@ func _RepoCredsService_DeleteRepositoryCredentials_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _RepoCredsService_DeleteWriteRepositoryCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoCredsDeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepoCredsServiceServer).DeleteWriteRepositoryCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repocreds.RepoCredsService/DeleteWriteRepositoryCredentials", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepoCredsServiceServer).DeleteWriteRepositoryCredentials(ctx, req.(*RepoCredsDeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _RepoCredsService_serviceDesc = grpc.ServiceDesc{ ServiceName: "repocreds.RepoCredsService", HandlerType: (*RepoCredsServiceServer)(nil), @@ -498,18 +639,34 @@ var _RepoCredsService_serviceDesc = grpc.ServiceDesc{ MethodName: "ListRepositoryCredentials", Handler: _RepoCredsService_ListRepositoryCredentials_Handler, }, + { + MethodName: "ListWriteRepositoryCredentials", + Handler: _RepoCredsService_ListWriteRepositoryCredentials_Handler, + }, { MethodName: "CreateRepositoryCredentials", Handler: _RepoCredsService_CreateRepositoryCredentials_Handler, }, + { + MethodName: "CreateWriteRepositoryCredentials", + Handler: _RepoCredsService_CreateWriteRepositoryCredentials_Handler, + }, { MethodName: "UpdateRepositoryCredentials", Handler: _RepoCredsService_UpdateRepositoryCredentials_Handler, }, + { + MethodName: "UpdateWriteRepositoryCredentials", + Handler: _RepoCredsService_UpdateWriteRepositoryCredentials_Handler, + }, { MethodName: "DeleteRepositoryCredentials", Handler: _RepoCredsService_DeleteRepositoryCredentials_Handler, }, + { + MethodName: "DeleteWriteRepositoryCredentials", + Handler: _RepoCredsService_DeleteWriteRepositoryCredentials_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "server/repocreds/repocreds.proto", diff --git a/pkg/apiclient/repocreds/repocreds.pb.gw.go b/pkg/apiclient/repocreds/repocreds.pb.gw.go index cbf003fbfaa54..699a8620935a3 100644 --- a/pkg/apiclient/repocreds/repocreds.pb.gw.go +++ b/pkg/apiclient/repocreds/repocreds.pb.gw.go @@ -69,6 +69,42 @@ func local_request_RepoCredsService_ListRepositoryCredentials_0(ctx context.Cont } +var ( + filter_RepoCredsService_ListWriteRepositoryCredentials_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_RepoCredsService_ListWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsQuery + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepoCredsService_ListWriteRepositoryCredentials_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListWriteRepositoryCredentials(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepoCredsService_ListWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, server RepoCredsServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsQuery + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepoCredsService_ListWriteRepositoryCredentials_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListWriteRepositoryCredentials(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_RepoCredsService_CreateRepositoryCredentials_0 = &utilities.DoubleArray{Encoding: map[string]int{"creds": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -121,6 +157,58 @@ func local_request_RepoCredsService_CreateRepositoryCredentials_0(ctx context.Co } +var ( + filter_RepoCredsService_CreateWriteRepositoryCredentials_0 = &utilities.DoubleArray{Encoding: map[string]int{"creds": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_RepoCredsService_CreateWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsCreateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Creds); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepoCredsService_CreateWriteRepositoryCredentials_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateWriteRepositoryCredentials(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepoCredsService_CreateWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, server RepoCredsServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsCreateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Creds); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepoCredsService_CreateWriteRepositoryCredentials_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateWriteRepositoryCredentials(ctx, &protoReq) + return msg, metadata, err + +} + func request_RepoCredsService_UpdateRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RepoCredsUpdateRequest var metadata runtime.ServerMetadata @@ -191,6 +279,76 @@ func local_request_RepoCredsService_UpdateRepositoryCredentials_0(ctx context.Co } +func request_RepoCredsService_UpdateWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsUpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Creds); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creds.url"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creds.url") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "creds.url", val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creds.url", err) + } + + msg, err := client.UpdateWriteRepositoryCredentials(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepoCredsService_UpdateWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, server RepoCredsServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsUpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Creds); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["creds.url"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "creds.url") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "creds.url", val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "creds.url", err) + } + + msg, err := server.UpdateWriteRepositoryCredentials(ctx, &protoReq) + return msg, metadata, err + +} + func request_RepoCredsService_DeleteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RepoCredsDeleteRequest var metadata runtime.ServerMetadata @@ -245,6 +403,60 @@ func local_request_RepoCredsService_DeleteRepositoryCredentials_0(ctx context.Co } +func request_RepoCredsService_DeleteWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, client RepoCredsServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsDeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["url"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "url") + } + + protoReq.Url, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "url", err) + } + + msg, err := client.DeleteWriteRepositoryCredentials(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepoCredsService_DeleteWriteRepositoryCredentials_0(ctx context.Context, marshaler runtime.Marshaler, server RepoCredsServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCredsDeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["url"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "url") + } + + protoReq.Url, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "url", err) + } + + msg, err := server.DeleteWriteRepositoryCredentials(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterRepoCredsServiceHandlerServer registers the http handlers for service RepoCredsService to "mux". // UnaryRPC :call RepoCredsServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -274,6 +486,29 @@ func RegisterRepoCredsServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("GET", pattern_RepoCredsService_ListWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepoCredsService_ListWriteRepositoryCredentials_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_ListWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RepoCredsService_CreateRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -297,6 +532,29 @@ func RegisterRepoCredsServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_RepoCredsService_CreateWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepoCredsService_CreateWriteRepositoryCredentials_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_CreateWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PUT", pattern_RepoCredsService_UpdateRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -320,6 +578,29 @@ func RegisterRepoCredsServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("PUT", pattern_RepoCredsService_UpdateWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepoCredsService_UpdateWriteRepositoryCredentials_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_UpdateWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_RepoCredsService_DeleteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -343,6 +624,29 @@ func RegisterRepoCredsServiceHandlerServer(ctx context.Context, mux *runtime.Ser }) + mux.Handle("DELETE", pattern_RepoCredsService_DeleteWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepoCredsService_DeleteWriteRepositoryCredentials_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_DeleteWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -404,6 +708,26 @@ func RegisterRepoCredsServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("GET", pattern_RepoCredsService_ListWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepoCredsService_ListWriteRepositoryCredentials_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_ListWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RepoCredsService_CreateRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -424,6 +748,26 @@ func RegisterRepoCredsServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("POST", pattern_RepoCredsService_CreateWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepoCredsService_CreateWriteRepositoryCredentials_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_CreateWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PUT", pattern_RepoCredsService_UpdateRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -444,6 +788,26 @@ func RegisterRepoCredsServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("PUT", pattern_RepoCredsService_UpdateWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepoCredsService_UpdateWriteRepositoryCredentials_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_UpdateWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_RepoCredsService_DeleteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -464,25 +828,61 @@ func RegisterRepoCredsServiceHandlerClient(ctx context.Context, mux *runtime.Ser }) + mux.Handle("DELETE", pattern_RepoCredsService_DeleteWriteRepositoryCredentials_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepoCredsService_DeleteWriteRepositoryCredentials_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepoCredsService_DeleteWriteRepositoryCredentials_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( pattern_RepoCredsService_ListRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repocreds"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_ListWriteRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "write-repocreds"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_CreateRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repocreds"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_CreateWriteRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "write-repocreds"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_UpdateRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repocreds", "creds.url"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_UpdateWriteRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "write-repocreds", "creds.url"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepoCredsService_DeleteRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repocreds", "url"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RepoCredsService_DeleteWriteRepositoryCredentials_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "write-repocreds", "url"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( forward_RepoCredsService_ListRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_ListWriteRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_CreateRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_CreateWriteRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_UpdateRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_UpdateWriteRepositoryCredentials_0 = runtime.ForwardResponseMessage + forward_RepoCredsService_DeleteRepositoryCredentials_0 = runtime.ForwardResponseMessage + + forward_RepoCredsService_DeleteWriteRepositoryCredentials_0 = runtime.ForwardResponseMessage ) diff --git a/pkg/apiclient/repository/repository.pb.go b/pkg/apiclient/repository/repository.pb.go index 8dbb20ce7bc70..feb1003e454b5 100644 --- a/pkg/apiclient/repository/repository.pb.go +++ b/pkg/apiclient/repository/repository.pb.go @@ -730,81 +730,89 @@ func init() { } var fileDescriptor_8d38260443475705 = []byte{ - // 1178 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x5d, 0x6f, 0x1b, 0x45, - 0x17, 0xd6, 0x26, 0x8d, 0x93, 0x9c, 0x7c, 0xd4, 0x99, 0xe4, 0xed, 0xbb, 0xb8, 0x6e, 0x1a, 0x6d, - 0x4b, 0x15, 0xa2, 0xb2, 0x6e, 0x8c, 0x10, 0xa8, 0x08, 0x24, 0xe7, 0x43, 0x4d, 0x44, 0x44, 0xca, - 0x56, 0xe1, 0x02, 0x81, 0xd0, 0x64, 0x7d, 0x62, 0x6f, 0xbb, 0xde, 0x9d, 0xce, 0x8c, 0x4d, 0xad, - 0xaa, 0x37, 0x5c, 0x21, 0xc1, 0x0d, 0x42, 0x48, 0xdc, 0x21, 0x24, 0x24, 0x2e, 0xf8, 0x23, 0x5c, - 0x22, 0xf1, 0x07, 0x50, 0xc4, 0x8f, 0xe0, 0x0a, 0xa1, 0x99, 0x59, 0xef, 0xae, 0x13, 0xdb, 0x49, - 0x45, 0xc8, 0xdd, 0xcc, 0x73, 0xce, 0x9e, 0xf3, 0xcc, 0xb3, 0xe7, 0x9c, 0x9d, 0x05, 0x47, 0x20, - 0xef, 0x20, 0xaf, 0x70, 0x64, 0xb1, 0x08, 0x64, 0xcc, 0xbb, 0xb9, 0xa5, 0xcb, 0x78, 0x2c, 0x63, - 0x02, 0x19, 0x52, 0x2a, 0x37, 0xe2, 0xb8, 0x11, 0x62, 0x85, 0xb2, 0xa0, 0x42, 0xa3, 0x28, 0x96, - 0x54, 0x06, 0x71, 0x24, 0x8c, 0x67, 0x69, 0xaf, 0x11, 0xc8, 0x66, 0xfb, 0xd0, 0xf5, 0xe3, 0x56, - 0x85, 0xf2, 0x46, 0xcc, 0x78, 0xfc, 0x58, 0x2f, 0x5e, 0xf7, 0xeb, 0x95, 0x4e, 0xb5, 0xc2, 0x9e, - 0x34, 0xd4, 0x93, 0xa2, 0x42, 0x19, 0x0b, 0x03, 0x5f, 0x3f, 0x5b, 0xe9, 0xac, 0xd3, 0x90, 0x35, - 0xe9, 0x7a, 0xa5, 0x81, 0x11, 0x72, 0x2a, 0xb1, 0x9e, 0x44, 0xdb, 0x3e, 0x23, 0x9a, 0xa6, 0x75, - 0x26, 0x7d, 0xa7, 0x0b, 0x73, 0x1e, 0xb2, 0xb8, 0xc6, 0x98, 0xf8, 0xb0, 0x8d, 0xbc, 0x4b, 0x08, - 0x5c, 0x51, 0x4e, 0xb6, 0xb5, 0x62, 0xad, 0x4e, 0x7b, 0x7a, 0x4d, 0x4a, 0x30, 0xc5, 0xb1, 0x13, - 0x88, 0x20, 0x8e, 0xec, 0x31, 0x8d, 0xa7, 0x7b, 0x62, 0xc3, 0x24, 0x65, 0xec, 0x03, 0xda, 0x42, - 0x7b, 0x5c, 0x9b, 0x7a, 0x5b, 0xb2, 0x0c, 0x40, 0x19, 0x7b, 0xc8, 0xe3, 0xc7, 0xe8, 0x4b, 0xfb, - 0x8a, 0x36, 0xe6, 0x10, 0x67, 0x1d, 0x26, 0x6b, 0x8c, 0xed, 0x46, 0x47, 0xb1, 0x4a, 0x2a, 0xbb, - 0x0c, 0x7b, 0x49, 0xd5, 0x5a, 0x61, 0x8c, 0xca, 0x66, 0x92, 0x50, 0xaf, 0x9d, 0xbf, 0x2c, 0x58, - 0x4c, 0xe8, 0x6e, 0xa1, 0xa4, 0x41, 0x98, 0x90, 0x6e, 0x40, 0x41, 0xc4, 0x6d, 0xee, 0x9b, 0x08, - 0x33, 0xd5, 0x7d, 0x37, 0x53, 0xc7, 0xed, 0xa9, 0xa3, 0x17, 0x9f, 0xf9, 0x75, 0xb7, 0x53, 0x75, - 0xd9, 0x93, 0x86, 0xab, 0xb4, 0x76, 0x73, 0x5a, 0xbb, 0x3d, 0xad, 0xdd, 0x5a, 0x06, 0x3e, 0xd2, - 0x61, 0xbd, 0x24, 0x7c, 0xfe, 0xb4, 0x63, 0xa3, 0x4e, 0x3b, 0x7e, 0xf2, 0xb4, 0x64, 0x05, 0x66, - 0x4c, 0x8c, 0xdd, 0xa8, 0x8e, 0xcf, 0xb4, 0x1c, 0x13, 0x5e, 0x1e, 0x22, 0x65, 0x98, 0xee, 0x20, - 0x57, 0xa2, 0xee, 0xd6, 0xed, 0x09, 0x6d, 0xcf, 0x00, 0xe7, 0x5d, 0x28, 0xf6, 0x5e, 0x94, 0x87, - 0x82, 0xc5, 0x91, 0x40, 0xf2, 0x1a, 0x4c, 0x04, 0x12, 0x5b, 0xc2, 0xb6, 0x56, 0xc6, 0x57, 0x67, - 0xaa, 0x8b, 0x6e, 0xee, 0xf5, 0x26, 0xd2, 0x7a, 0xc6, 0xc3, 0xf1, 0x61, 0x5a, 0x3d, 0x3e, 0xfc, - 0x1d, 0x3b, 0x30, 0x7b, 0x14, 0xab, 0xa3, 0xe2, 0x11, 0x47, 0x61, 0x64, 0x9f, 0xf2, 0xfa, 0xb0, - 0xb3, 0xce, 0xe8, 0xfc, 0x38, 0x01, 0x57, 0x35, 0x49, 0xdf, 0x47, 0x31, 0xba, 0x9e, 0xda, 0x02, - 0x79, 0x94, 0xc9, 0x98, 0xee, 0x95, 0x8d, 0x51, 0x21, 0x3e, 0x8f, 0x79, 0x3d, 0xc9, 0x90, 0xee, - 0xc9, 0x6d, 0x98, 0x13, 0xa2, 0xf9, 0x90, 0x07, 0x1d, 0x2a, 0xf1, 0x7d, 0xec, 0x26, 0x45, 0xd5, - 0x0f, 0xaa, 0x08, 0x41, 0x24, 0xd0, 0x6f, 0x73, 0xd4, 0x32, 0x4e, 0x79, 0xe9, 0x9e, 0xdc, 0x85, - 0x05, 0x19, 0x8a, 0xcd, 0x30, 0xc0, 0x48, 0x6e, 0x22, 0x97, 0x5b, 0x54, 0x52, 0xbb, 0xa0, 0xa3, - 0x9c, 0x36, 0x90, 0x35, 0x28, 0xf6, 0x81, 0x2a, 0xe5, 0xa4, 0x76, 0x3e, 0x85, 0xa7, 0x25, 0x3c, - 0xdd, 0x5f, 0xc2, 0xfa, 0x8c, 0x60, 0x30, 0x7d, 0xbe, 0x32, 0x4c, 0x63, 0x44, 0x0f, 0x43, 0xdc, - 0xf7, 0x03, 0x7b, 0x46, 0xd3, 0xcb, 0x00, 0x72, 0x0f, 0x16, 0x4d, 0xe5, 0xd6, 0x94, 0xaa, 0xe9, - 0x39, 0x67, 0x75, 0x80, 0x41, 0x26, 0x55, 0x57, 0x29, 0xbc, 0xbb, 0x65, 0xcf, 0xad, 0x58, 0xab, - 0xe3, 0x5e, 0x1e, 0x22, 0x6f, 0xc3, 0xff, 0xb3, 0x6d, 0x24, 0x24, 0x0d, 0x43, 0x5d, 0xda, 0xbb, - 0x5b, 0xf6, 0xbc, 0xf6, 0x1e, 0x66, 0x26, 0xef, 0x41, 0x29, 0x35, 0x6d, 0x47, 0x12, 0x39, 0xe3, - 0x81, 0xc0, 0x0d, 0x2a, 0xf0, 0x80, 0x87, 0xf6, 0x55, 0x4d, 0x6a, 0x84, 0x07, 0x59, 0x82, 0x09, - 0xc6, 0xe3, 0x67, 0x5d, 0xbb, 0xa8, 0x5d, 0xcd, 0x46, 0xf5, 0x10, 0x4b, 0x4a, 0x68, 0xc1, 0xf4, - 0x50, 0xb2, 0x25, 0x55, 0x58, 0x6a, 0xf8, 0xec, 0x11, 0xf2, 0x4e, 0xe0, 0x63, 0xcd, 0xf7, 0xe3, - 0x76, 0xa4, 0x35, 0x27, 0xda, 0x6d, 0xa0, 0x8d, 0xb8, 0x40, 0x74, 0x8d, 0xee, 0x48, 0xc9, 0x36, - 0xa8, 0x08, 0xfc, 0x5a, 0x5b, 0x36, 0xed, 0x45, 0x2d, 0xec, 0x00, 0x8b, 0x33, 0x0f, 0xb3, 0xaa, - 0x44, 0x7b, 0x3d, 0xe4, 0xfc, 0x6c, 0xc1, 0x82, 0x02, 0x36, 0x39, 0x52, 0x89, 0x1e, 0x3e, 0x6d, - 0xa3, 0x90, 0xe4, 0x93, 0x5c, 0xd5, 0xce, 0x54, 0x77, 0xfe, 0xdd, 0x38, 0xf1, 0xd2, 0xae, 0x4c, - 0xea, 0xff, 0x1a, 0x14, 0xda, 0x4c, 0x20, 0x97, 0x49, 0x97, 0x25, 0x3b, 0x55, 0x1b, 0x3e, 0xc7, - 0xba, 0xd8, 0x8f, 0xc2, 0xae, 0x2e, 0xfe, 0x29, 0x2f, 0x03, 0x9c, 0xa7, 0x86, 0xe8, 0x01, 0xab, - 0x5f, 0x16, 0xd1, 0xea, 0xdf, 0xf3, 0x26, 0xa7, 0x01, 0x13, 0xf1, 0xc9, 0xd7, 0x16, 0x5c, 0xd9, - 0x0b, 0x84, 0x24, 0xff, 0xcb, 0x0f, 0x9c, 0x74, 0xbc, 0x94, 0xf6, 0x2e, 0x8a, 0x85, 0x4a, 0xe2, - 0xdc, 0xfc, 0xe2, 0xf7, 0x3f, 0xbf, 0x1d, 0xbb, 0x46, 0x96, 0xf4, 0x67, 0xb5, 0xb3, 0x9e, 0x7d, - 0xc3, 0x02, 0x14, 0x5f, 0x8e, 0x59, 0xe4, 0x2b, 0x0b, 0xc6, 0x1f, 0xe0, 0x50, 0x36, 0x17, 0xa6, - 0x89, 0x73, 0x4b, 0x33, 0xb9, 0x41, 0xae, 0x0f, 0x62, 0x52, 0x79, 0xae, 0x76, 0x2f, 0xc8, 0x77, - 0x16, 0x14, 0x15, 0x6f, 0x2f, 0x67, 0xbb, 0x1c, 0xa1, 0xca, 0xa3, 0x84, 0x22, 0x9f, 0xc2, 0x94, - 0xa1, 0x75, 0x34, 0x94, 0x4e, 0xb1, 0x1f, 0x3e, 0x12, 0xce, 0xaa, 0x0e, 0xe9, 0x90, 0x95, 0x11, - 0x27, 0xae, 0x70, 0x15, 0xb2, 0x65, 0xc2, 0xab, 0xcf, 0x13, 0x79, 0xe5, 0x64, 0xf8, 0xf4, 0x76, - 0x51, 0x2a, 0x0f, 0x32, 0xa5, 0xbd, 0x78, 0xae, 0x74, 0x54, 0xa5, 0xf8, 0xc6, 0x82, 0xb9, 0x07, - 0x28, 0xb3, 0x7b, 0x00, 0xb9, 0x39, 0x20, 0x72, 0xfe, 0x8e, 0x50, 0x72, 0x86, 0x3b, 0xa4, 0x04, - 0xde, 0xd1, 0x04, 0xde, 0x74, 0xee, 0x0d, 0x26, 0x60, 0xbe, 0xd6, 0x3a, 0xce, 0x81, 0xb7, 0xa7, - 0xa9, 0xd4, 0x4d, 0x84, 0xfb, 0xd6, 0x1a, 0xe9, 0x68, 0x4a, 0x3b, 0x18, 0xb6, 0x36, 0x9b, 0x94, - 0xcb, 0xa1, 0x32, 0x2f, 0xe7, 0xe1, 0xcc, 0x3d, 0x25, 0xe1, 0x6a, 0x12, 0xab, 0xe4, 0xce, 0x28, - 0x15, 0x9a, 0x18, 0xb6, 0x7c, 0x93, 0xe6, 0x7b, 0x0b, 0x0a, 0x66, 0x7a, 0x91, 0x1b, 0x27, 0x33, - 0xf6, 0x4d, 0xb5, 0x0b, 0x6c, 0x85, 0x57, 0x35, 0xc7, 0xb2, 0x33, 0xb0, 0xd6, 0xee, 0xeb, 0xe1, - 0xa1, 0x5a, 0xf3, 0x07, 0x0b, 0x8a, 0x3d, 0x0a, 0xbd, 0x67, 0x2f, 0x8f, 0xa4, 0x73, 0x36, 0x49, - 0xf2, 0x93, 0x05, 0x05, 0x33, 0x51, 0x4f, 0xf3, 0xea, 0x9b, 0xb4, 0x17, 0xc8, 0x6b, 0xdd, 0xbc, - 0xe0, 0xd2, 0x88, 0x32, 0xd7, 0x54, 0x5e, 0x64, 0x42, 0xfe, 0x62, 0x41, 0xb1, 0x47, 0x67, 0xb8, - 0x90, 0xff, 0x15, 0x61, 0xf7, 0xe5, 0x08, 0x13, 0x0a, 0x85, 0x2d, 0x0c, 0x51, 0xe2, 0xb0, 0x16, - 0xb0, 0x4f, 0xc2, 0x69, 0xf1, 0xdf, 0x31, 0x33, 0x76, 0x6d, 0xd4, 0x8c, 0x55, 0x82, 0x34, 0xa1, - 0x68, 0x52, 0xe4, 0xf4, 0x78, 0xe9, 0x64, 0xb7, 0xce, 0x91, 0x8c, 0x3c, 0x87, 0xf9, 0x8f, 0x68, - 0x18, 0x28, 0x65, 0xcd, 0xbd, 0x96, 0x5c, 0x3f, 0x35, 0x49, 0xb2, 0xfb, 0xee, 0x88, 0x6c, 0x55, - 0x9d, 0xed, 0xae, 0x73, 0x7b, 0x54, 0x5f, 0x77, 0x92, 0x54, 0x46, 0xc9, 0x8d, 0xed, 0x5f, 0x8f, - 0x97, 0xad, 0xdf, 0x8e, 0x97, 0xad, 0x3f, 0x8e, 0x97, 0xad, 0x8f, 0xdf, 0x3a, 0xdf, 0x1f, 0xa4, - 0xaf, 0x2f, 0xa6, 0xb9, 0x7f, 0xbd, 0xc3, 0x82, 0xfe, 0xd9, 0x7b, 0xe3, 0x9f, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x56, 0xc6, 0x8e, 0x59, 0xd1, 0x0e, 0x00, 0x00, + // 1304 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xc7, 0xb5, 0x49, 0xe3, 0x26, 0x27, 0x4d, 0xeb, 0x4e, 0x9a, 0xb2, 0xb8, 0x69, 0x1a, 0xb6, + 0xa5, 0x4a, 0xa3, 0x76, 0xdd, 0x18, 0x10, 0x55, 0x11, 0x48, 0x6e, 0x52, 0xb5, 0x11, 0x11, 0x2d, + 0x5b, 0x15, 0x24, 0x04, 0x42, 0xd3, 0xf5, 0x89, 0xbd, 0xed, 0x7a, 0x77, 0x3a, 0x33, 0x76, 0x6b, + 0x55, 0xbd, 0xe1, 0x02, 0x21, 0xc1, 0x0d, 0x42, 0x20, 0xae, 0xf8, 0x90, 0x90, 0x90, 0xe0, 0x9e, + 0x67, 0xe0, 0x12, 0x89, 0x17, 0x40, 0x15, 0x0f, 0xc1, 0x25, 0x9a, 0x99, 0xf5, 0xee, 0xda, 0xf1, + 0x47, 0xaa, 0x26, 0xb9, 0x9b, 0x39, 0x67, 0xf6, 0x9c, 0xdf, 0xfc, 0xe7, 0xcc, 0x87, 0x0d, 0x8e, + 0x40, 0xde, 0x46, 0x5e, 0xe6, 0xc8, 0x62, 0x11, 0xc8, 0x98, 0x77, 0x72, 0x4d, 0x97, 0xf1, 0x58, + 0xc6, 0x04, 0x32, 0x4b, 0x69, 0xb1, 0x1e, 0xc7, 0xf5, 0x10, 0xcb, 0x94, 0x05, 0x65, 0x1a, 0x45, + 0xb1, 0xa4, 0x32, 0x88, 0x23, 0x61, 0x46, 0x96, 0xb6, 0xea, 0x81, 0x6c, 0xb4, 0xee, 0xb9, 0x7e, + 0xdc, 0x2c, 0x53, 0x5e, 0x8f, 0x19, 0x8f, 0xef, 0xeb, 0xc6, 0x25, 0xbf, 0x56, 0x6e, 0x57, 0xca, + 0xec, 0x41, 0x5d, 0x7d, 0x29, 0xca, 0x94, 0xb1, 0x30, 0xf0, 0xf5, 0xb7, 0xe5, 0xf6, 0x1a, 0x0d, + 0x59, 0x83, 0xae, 0x95, 0xeb, 0x18, 0x21, 0xa7, 0x12, 0x6b, 0x49, 0xb4, 0xeb, 0x63, 0xa2, 0x69, + 0xac, 0xb1, 0xf8, 0x4e, 0x07, 0xe6, 0x3c, 0x64, 0x71, 0x95, 0x31, 0xf1, 0x7e, 0x0b, 0x79, 0x87, + 0x10, 0x38, 0xa4, 0x06, 0xd9, 0xd6, 0xb2, 0xb5, 0x32, 0xe3, 0xe9, 0x36, 0x29, 0xc1, 0x34, 0xc7, + 0x76, 0x20, 0x82, 0x38, 0xb2, 0x27, 0xb4, 0x3d, 0xed, 0x13, 0x1b, 0x0e, 0x53, 0xc6, 0xde, 0xa3, + 0x4d, 0xb4, 0x27, 0xb5, 0xab, 0xdb, 0x25, 0x4b, 0x00, 0x94, 0xb1, 0xdb, 0x3c, 0xbe, 0x8f, 0xbe, + 0xb4, 0x0f, 0x69, 0x67, 0xce, 0xe2, 0xac, 0xc1, 0xe1, 0x2a, 0x63, 0x9b, 0xd1, 0x76, 0xac, 0x92, + 0xca, 0x0e, 0xc3, 0x6e, 0x52, 0xd5, 0x56, 0x36, 0x46, 0x65, 0x23, 0x49, 0xa8, 0xdb, 0xce, 0x7f, + 0x16, 0xcc, 0x27, 0xb8, 0x1b, 0x28, 0x69, 0x10, 0x26, 0xd0, 0x75, 0x28, 0x88, 0xb8, 0xc5, 0x7d, + 0x13, 0x61, 0xb6, 0x72, 0xcb, 0xcd, 0xd4, 0x71, 0xbb, 0xea, 0xe8, 0xc6, 0xa7, 0x7e, 0xcd, 0x6d, + 0x57, 0x5c, 0xf6, 0xa0, 0xee, 0x2a, 0xad, 0xdd, 0x9c, 0xd6, 0x6e, 0x57, 0x6b, 0xb7, 0x9a, 0x19, + 0xef, 0xe8, 0xb0, 0x5e, 0x12, 0x3e, 0x3f, 0xdb, 0x89, 0x51, 0xb3, 0x9d, 0xec, 0x9f, 0x2d, 0x59, + 0x86, 0x59, 0x13, 0x63, 0x33, 0xaa, 0xe1, 0x63, 0x2d, 0xc7, 0x94, 0x97, 0x37, 0x91, 0x45, 0x98, + 0x69, 0x23, 0x57, 0xa2, 0x6e, 0xd6, 0xec, 0x29, 0xed, 0xcf, 0x0c, 0xce, 0xdb, 0x50, 0xec, 0x2e, + 0x94, 0x87, 0x82, 0xc5, 0x91, 0x40, 0x72, 0x01, 0xa6, 0x02, 0x89, 0x4d, 0x61, 0x5b, 0xcb, 0x93, + 0x2b, 0xb3, 0x95, 0x79, 0x37, 0xb7, 0xbc, 0x89, 0xb4, 0x9e, 0x19, 0xe1, 0xf8, 0x30, 0xa3, 0x3e, + 0x1f, 0xbe, 0xc6, 0x0e, 0x1c, 0xd9, 0x8e, 0xd5, 0x54, 0x71, 0x9b, 0xa3, 0x30, 0xb2, 0x4f, 0x7b, + 0x3d, 0xb6, 0x71, 0x73, 0x74, 0x7e, 0x9e, 0x82, 0x63, 0x1a, 0xd2, 0xf7, 0x51, 0x8c, 0xae, 0xa7, + 0x96, 0x40, 0x1e, 0x65, 0x32, 0xa6, 0x7d, 0xe5, 0x63, 0x54, 0x88, 0x47, 0x31, 0xaf, 0x25, 0x19, + 0xd2, 0x3e, 0x39, 0x07, 0x73, 0x42, 0x34, 0x6e, 0xf3, 0xa0, 0x4d, 0x25, 0xbe, 0x8b, 0x9d, 0xa4, + 0xa8, 0x7a, 0x8d, 0x2a, 0x42, 0x10, 0x09, 0xf4, 0x5b, 0x1c, 0xb5, 0x8c, 0xd3, 0x5e, 0xda, 0x27, + 0x17, 0xe1, 0xb8, 0x0c, 0xc5, 0x7a, 0x18, 0x60, 0x24, 0xd7, 0x91, 0xcb, 0x0d, 0x2a, 0xa9, 0x5d, + 0xd0, 0x51, 0x76, 0x3a, 0xc8, 0x2a, 0x14, 0x7b, 0x8c, 0x2a, 0xe5, 0x61, 0x3d, 0x78, 0x87, 0x3d, + 0x2d, 0xe1, 0x99, 0xde, 0x12, 0xd6, 0x73, 0x04, 0x63, 0xd3, 0xf3, 0x5b, 0x84, 0x19, 0x8c, 0xe8, + 0xbd, 0x10, 0x6f, 0xf9, 0x81, 0x3d, 0xab, 0xf1, 0x32, 0x03, 0xb9, 0x0c, 0xf3, 0xa6, 0x72, 0xab, + 0x4a, 0xd5, 0x74, 0x9e, 0x47, 0x74, 0x80, 0x41, 0x2e, 0x55, 0x57, 0xa9, 0x79, 0x73, 0xc3, 0x9e, + 0x5b, 0xb6, 0x56, 0x26, 0xbd, 0xbc, 0x89, 0x5c, 0x81, 0x97, 0xb2, 0x6e, 0x24, 0x24, 0x0d, 0x43, + 0x5d, 0xda, 0x9b, 0x1b, 0xf6, 0x51, 0x3d, 0x7a, 0x98, 0x9b, 0xbc, 0x03, 0xa5, 0xd4, 0x75, 0x3d, + 0x92, 0xc8, 0x19, 0x0f, 0x04, 0x5e, 0xa3, 0x02, 0xef, 0xf2, 0xd0, 0x3e, 0xa6, 0xa1, 0x46, 0x8c, + 0x20, 0x27, 0x60, 0x8a, 0xf1, 0xf8, 0x71, 0xc7, 0x2e, 0xea, 0xa1, 0xa6, 0xa3, 0xf6, 0x10, 0x4b, + 0x4a, 0xe8, 0xb8, 0xd9, 0x43, 0x49, 0x97, 0x54, 0xe0, 0x44, 0xdd, 0x67, 0x77, 0x90, 0xb7, 0x03, + 0x1f, 0xab, 0xbe, 0x1f, 0xb7, 0x22, 0xad, 0x39, 0xd1, 0xc3, 0x06, 0xfa, 0x88, 0x0b, 0x44, 0xd7, + 0xe8, 0x4d, 0x29, 0xd9, 0x35, 0x2a, 0x02, 0xbf, 0xda, 0x92, 0x0d, 0x7b, 0x5e, 0x0b, 0x3b, 0xc0, + 0xe3, 0x1c, 0x85, 0x23, 0xaa, 0x44, 0xbb, 0x7b, 0xc8, 0xf9, 0xd5, 0x82, 0xe3, 0xca, 0xb0, 0xce, + 0x91, 0x4a, 0xf4, 0xf0, 0x61, 0x0b, 0x85, 0x24, 0x1f, 0xe7, 0xaa, 0x76, 0xb6, 0x72, 0xf3, 0xc5, + 0x8e, 0x13, 0x2f, 0xdd, 0x95, 0x49, 0xfd, 0x9f, 0x84, 0x42, 0x8b, 0x09, 0xe4, 0x32, 0xd9, 0x65, + 0x49, 0x4f, 0xd5, 0x86, 0xcf, 0xb1, 0x26, 0x6e, 0x45, 0x61, 0x47, 0x17, 0xff, 0xb4, 0x97, 0x19, + 0x9c, 0x87, 0x06, 0xf4, 0x2e, 0xab, 0x1d, 0x14, 0x68, 0xe5, 0x87, 0x93, 0x26, 0xa7, 0x31, 0x26, + 0xe2, 0x93, 0xaf, 0x2c, 0x38, 0xb4, 0x15, 0x08, 0x49, 0x16, 0xf2, 0x07, 0x4e, 0x7a, 0xbc, 0x94, + 0xb6, 0xf6, 0x8a, 0x42, 0x25, 0x71, 0xce, 0x7c, 0xf6, 0xf7, 0xbf, 0xdf, 0x4c, 0x9c, 0x24, 0x27, + 0xf4, 0xb5, 0xda, 0x5e, 0xcb, 0xee, 0xb0, 0x00, 0xc5, 0x17, 0x13, 0x16, 0xf9, 0xd2, 0x82, 0xc9, + 0x1b, 0x38, 0x94, 0x66, 0xcf, 0x34, 0x71, 0xce, 0x6a, 0x92, 0xd3, 0xe4, 0xd4, 0x20, 0x92, 0xf2, + 0x13, 0xd5, 0x7b, 0x4a, 0xbe, 0xb3, 0x60, 0xfa, 0x06, 0xca, 0x0f, 0x79, 0x20, 0x71, 0xff, 0x91, + 0x2e, 0x68, 0xa4, 0xb3, 0xe4, 0x95, 0x2e, 0xd2, 0x23, 0x95, 0xf7, 0xd2, 0x20, 0xb0, 0x6f, 0x2d, + 0x28, 0x2a, 0x41, 0xbd, 0x9c, 0xef, 0x60, 0x56, 0x70, 0x71, 0xd4, 0x0a, 0x92, 0x9f, 0x2c, 0x58, + 0x50, 0xc3, 0xb4, 0x62, 0x07, 0x0f, 0xe7, 0x68, 0xb8, 0x45, 0x52, 0x1a, 0xae, 0x20, 0xf9, 0x04, + 0xa6, 0x8d, 0x72, 0xdb, 0x43, 0xa1, 0x8a, 0xbd, 0xe6, 0x6d, 0xe1, 0xac, 0xe8, 0xc0, 0x0e, 0x59, + 0x1e, 0x51, 0x2d, 0x65, 0xae, 0x42, 0x36, 0x4d, 0x78, 0x75, 0xb5, 0x93, 0x97, 0xfb, 0xc3, 0xa7, + 0x2f, 0xb3, 0xd2, 0xe2, 0x20, 0x57, 0x7a, 0x8e, 0xed, 0x2a, 0x1d, 0x55, 0x29, 0xbe, 0xb6, 0x60, + 0xee, 0x06, 0xca, 0xec, 0x0d, 0x45, 0xce, 0x0c, 0x88, 0x9c, 0x7f, 0x5f, 0x95, 0x9c, 0xe1, 0x03, + 0x52, 0x80, 0xb7, 0x34, 0xc0, 0x1b, 0xce, 0xe5, 0xc1, 0x00, 0xe6, 0xa5, 0xa3, 0xe3, 0xdc, 0xf5, + 0xb6, 0x34, 0x4a, 0xcd, 0x44, 0xb8, 0x6a, 0xad, 0x92, 0xb6, 0x46, 0xba, 0x89, 0x61, 0x73, 0xbd, + 0x41, 0xb9, 0x1c, 0x2a, 0xf3, 0x52, 0xde, 0x9c, 0x0d, 0x4f, 0x21, 0x5c, 0x0d, 0xb1, 0x42, 0xce, + 0x8f, 0x52, 0xa1, 0x81, 0x61, 0xd3, 0x37, 0x69, 0xbe, 0xb7, 0xa0, 0x60, 0x4e, 0x7e, 0x72, 0xba, + 0x3f, 0x63, 0xcf, 0x8d, 0xb0, 0x87, 0x7b, 0xf6, 0x55, 0x53, 0x71, 0xce, 0xc0, 0xed, 0x70, 0x55, + 0x1f, 0xbc, 0xea, 0x58, 0xfb, 0xd1, 0x82, 0x62, 0x17, 0xa1, 0xfb, 0xed, 0xc1, 0x41, 0x3a, 0xe3, + 0x21, 0xc9, 0x6f, 0x16, 0x2c, 0x98, 0xfc, 0xbd, 0x7b, 0xf7, 0x00, 0x31, 0x93, 0xaa, 0x77, 0x46, + 0xec, 0xde, 0x04, 0xf6, 0x17, 0x0b, 0x0a, 0xe6, 0xea, 0xdc, 0x49, 0xd7, 0x73, 0xa5, 0xee, 0x21, + 0xdd, 0x9a, 0xa9, 0xc6, 0xd2, 0x88, 0x3d, 0xa9, 0x51, 0x9e, 0x66, 0xab, 0xfe, 0xbb, 0x05, 0xc5, + 0x2e, 0xce, 0x70, 0x39, 0xf7, 0x0b, 0xd8, 0x7d, 0x3e, 0x60, 0xf2, 0x87, 0x05, 0x0b, 0x86, 0x65, + 0x6c, 0x05, 0xec, 0x17, 0xf2, 0xeb, 0x1a, 0xd9, 0x2d, 0x9d, 0x1f, 0x77, 0x03, 0xf6, 0x80, 0x53, + 0x28, 0x6c, 0x60, 0x88, 0xc3, 0xaf, 0x68, 0xbb, 0xdf, 0x9c, 0x1e, 0x31, 0xe7, 0xcd, 0x2b, 0x60, + 0x75, 0xd4, 0x2b, 0x40, 0xad, 0x64, 0x03, 0x8a, 0x26, 0x45, 0x4e, 0x95, 0xe7, 0x4e, 0x76, 0x76, + 0x17, 0xc9, 0x88, 0x80, 0x05, 0x93, 0xa9, 0x7f, 0x11, 0x9e, 0x3b, 0x5d, 0xf2, 0x9c, 0x58, 0xdd, + 0xc5, 0x73, 0xe2, 0x09, 0x1c, 0xfd, 0x80, 0x86, 0x81, 0x5a, 0x54, 0xf3, 0x73, 0x8f, 0x9c, 0xda, + 0x71, 0x49, 0x64, 0x3f, 0x03, 0x47, 0xe4, 0xac, 0xe8, 0x9c, 0x17, 0x9d, 0x73, 0xa3, 0x8e, 0xec, + 0x76, 0x92, 0x2a, 0x59, 0xbe, 0xcf, 0x2d, 0x98, 0xef, 0x66, 0xd7, 0x93, 0x7e, 0x31, 0x84, 0x2b, + 0x1a, 0xa1, 0xe2, 0xac, 0x8e, 0x9d, 0x76, 0x1f, 0xc8, 0xb5, 0xeb, 0x7f, 0x3e, 0x5b, 0xb2, 0xfe, + 0x7a, 0xb6, 0x64, 0xfd, 0xf3, 0x6c, 0xc9, 0xfa, 0xe8, 0xcd, 0xdd, 0xfd, 0xc3, 0xe3, 0xeb, 0x1f, + 0x8e, 0xb9, 0xff, 0x62, 0xee, 0x15, 0xf4, 0x9f, 0x31, 0xaf, 0xfd, 0x1f, 0x00, 0x00, 0xff, 0xff, + 0x85, 0x4e, 0xc2, 0x40, 0x71, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -823,8 +831,12 @@ type RepositoryServiceClient interface { List(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryList, error) // Get returns a repository or its credentials Get(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.Repository, error) + // GetWrite returns a repository or its write credentials + GetWrite(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.Repository, error) // ListRepositories gets a list of all configured repositories ListRepositories(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryList, error) + // ListWriteRepositories gets a list of all configured write repositories + ListWriteRepositories(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryList, error) ListRefs(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*apiclient.Refs, error) // ListApps returns list of apps in the repo ListApps(ctx context.Context, in *RepoAppsQuery, opts ...grpc.CallOption) (*RepoAppsResponse, error) @@ -836,16 +848,24 @@ type RepositoryServiceClient interface { Create(ctx context.Context, in *RepoCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) // CreateRepository creates a new repository configuration CreateRepository(ctx context.Context, in *RepoCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) + // CreateWriteRepository creates a new write repository configuration + CreateWriteRepository(ctx context.Context, in *RepoCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) // Update updates a repo or repo credential set Update(ctx context.Context, in *RepoUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) // UpdateRepository updates a repository configuration UpdateRepository(ctx context.Context, in *RepoUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) + // UpdateWriteRepository updates a write repository configuration + UpdateWriteRepository(ctx context.Context, in *RepoUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) // Delete deletes a repository from the configuration Delete(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*RepoResponse, error) // DeleteRepository deletes a repository from the configuration DeleteRepository(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*RepoResponse, error) + // DeleteWriteRepository deletes a write repository from the configuration + DeleteWriteRepository(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*RepoResponse, error) // ValidateAccess validates access to a repository with given parameters ValidateAccess(ctx context.Context, in *RepoAccessQuery, opts ...grpc.CallOption) (*RepoResponse, error) + // ValidateWriteAccess validates write access to a repository with given parameters + ValidateWriteAccess(ctx context.Context, in *RepoAccessQuery, opts ...grpc.CallOption) (*RepoResponse, error) } type repositoryServiceClient struct { @@ -875,6 +895,15 @@ func (c *repositoryServiceClient) Get(ctx context.Context, in *RepoQuery, opts . return out, nil } +func (c *repositoryServiceClient) GetWrite(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.Repository, error) { + out := new(v1alpha1.Repository) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/GetWrite", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repositoryServiceClient) ListRepositories(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryList, error) { out := new(v1alpha1.RepositoryList) err := c.cc.Invoke(ctx, "/repository.RepositoryService/ListRepositories", in, out, opts...) @@ -884,6 +913,15 @@ func (c *repositoryServiceClient) ListRepositories(ctx context.Context, in *Repo return out, nil } +func (c *repositoryServiceClient) ListWriteRepositories(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*v1alpha1.RepositoryList, error) { + out := new(v1alpha1.RepositoryList) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/ListWriteRepositories", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repositoryServiceClient) ListRefs(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*apiclient.Refs, error) { out := new(apiclient.Refs) err := c.cc.Invoke(ctx, "/repository.RepositoryService/ListRefs", in, out, opts...) @@ -939,6 +977,15 @@ func (c *repositoryServiceClient) CreateRepository(ctx context.Context, in *Repo return out, nil } +func (c *repositoryServiceClient) CreateWriteRepository(ctx context.Context, in *RepoCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) { + out := new(v1alpha1.Repository) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/CreateWriteRepository", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Deprecated: Do not use. func (c *repositoryServiceClient) Update(ctx context.Context, in *RepoUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) { out := new(v1alpha1.Repository) @@ -958,6 +1005,15 @@ func (c *repositoryServiceClient) UpdateRepository(ctx context.Context, in *Repo return out, nil } +func (c *repositoryServiceClient) UpdateWriteRepository(ctx context.Context, in *RepoUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Repository, error) { + out := new(v1alpha1.Repository) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/UpdateWriteRepository", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Deprecated: Do not use. func (c *repositoryServiceClient) Delete(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*RepoResponse, error) { out := new(RepoResponse) @@ -977,6 +1033,15 @@ func (c *repositoryServiceClient) DeleteRepository(ctx context.Context, in *Repo return out, nil } +func (c *repositoryServiceClient) DeleteWriteRepository(ctx context.Context, in *RepoQuery, opts ...grpc.CallOption) (*RepoResponse, error) { + out := new(RepoResponse) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/DeleteWriteRepository", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *repositoryServiceClient) ValidateAccess(ctx context.Context, in *RepoAccessQuery, opts ...grpc.CallOption) (*RepoResponse, error) { out := new(RepoResponse) err := c.cc.Invoke(ctx, "/repository.RepositoryService/ValidateAccess", in, out, opts...) @@ -986,14 +1051,27 @@ func (c *repositoryServiceClient) ValidateAccess(ctx context.Context, in *RepoAc return out, nil } +func (c *repositoryServiceClient) ValidateWriteAccess(ctx context.Context, in *RepoAccessQuery, opts ...grpc.CallOption) (*RepoResponse, error) { + out := new(RepoResponse) + err := c.cc.Invoke(ctx, "/repository.RepositoryService/ValidateWriteAccess", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // RepositoryServiceServer is the server API for RepositoryService service. type RepositoryServiceServer interface { // List returns list of repos or repository credentials List(context.Context, *RepoQuery) (*v1alpha1.RepositoryList, error) // Get returns a repository or its credentials Get(context.Context, *RepoQuery) (*v1alpha1.Repository, error) + // GetWrite returns a repository or its write credentials + GetWrite(context.Context, *RepoQuery) (*v1alpha1.Repository, error) // ListRepositories gets a list of all configured repositories ListRepositories(context.Context, *RepoQuery) (*v1alpha1.RepositoryList, error) + // ListWriteRepositories gets a list of all configured write repositories + ListWriteRepositories(context.Context, *RepoQuery) (*v1alpha1.RepositoryList, error) ListRefs(context.Context, *RepoQuery) (*apiclient.Refs, error) // ListApps returns list of apps in the repo ListApps(context.Context, *RepoAppsQuery) (*RepoAppsResponse, error) @@ -1005,16 +1083,24 @@ type RepositoryServiceServer interface { Create(context.Context, *RepoCreateRequest) (*v1alpha1.Repository, error) // CreateRepository creates a new repository configuration CreateRepository(context.Context, *RepoCreateRequest) (*v1alpha1.Repository, error) + // CreateWriteRepository creates a new write repository configuration + CreateWriteRepository(context.Context, *RepoCreateRequest) (*v1alpha1.Repository, error) // Update updates a repo or repo credential set Update(context.Context, *RepoUpdateRequest) (*v1alpha1.Repository, error) // UpdateRepository updates a repository configuration UpdateRepository(context.Context, *RepoUpdateRequest) (*v1alpha1.Repository, error) + // UpdateWriteRepository updates a write repository configuration + UpdateWriteRepository(context.Context, *RepoUpdateRequest) (*v1alpha1.Repository, error) // Delete deletes a repository from the configuration Delete(context.Context, *RepoQuery) (*RepoResponse, error) // DeleteRepository deletes a repository from the configuration DeleteRepository(context.Context, *RepoQuery) (*RepoResponse, error) + // DeleteWriteRepository deletes a write repository from the configuration + DeleteWriteRepository(context.Context, *RepoQuery) (*RepoResponse, error) // ValidateAccess validates access to a repository with given parameters ValidateAccess(context.Context, *RepoAccessQuery) (*RepoResponse, error) + // ValidateWriteAccess validates write access to a repository with given parameters + ValidateWriteAccess(context.Context, *RepoAccessQuery) (*RepoResponse, error) } // UnimplementedRepositoryServiceServer can be embedded to have forward compatible implementations. @@ -1027,9 +1113,15 @@ func (*UnimplementedRepositoryServiceServer) List(ctx context.Context, req *Repo func (*UnimplementedRepositoryServiceServer) Get(ctx context.Context, req *RepoQuery) (*v1alpha1.Repository, error) { return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") } +func (*UnimplementedRepositoryServiceServer) GetWrite(ctx context.Context, req *RepoQuery) (*v1alpha1.Repository, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWrite not implemented") +} func (*UnimplementedRepositoryServiceServer) ListRepositories(ctx context.Context, req *RepoQuery) (*v1alpha1.RepositoryList, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRepositories not implemented") } +func (*UnimplementedRepositoryServiceServer) ListWriteRepositories(ctx context.Context, req *RepoQuery) (*v1alpha1.RepositoryList, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWriteRepositories not implemented") +} func (*UnimplementedRepositoryServiceServer) ListRefs(ctx context.Context, req *RepoQuery) (*apiclient.Refs, error) { return nil, status.Errorf(codes.Unimplemented, "method ListRefs not implemented") } @@ -1048,21 +1140,33 @@ func (*UnimplementedRepositoryServiceServer) Create(ctx context.Context, req *Re func (*UnimplementedRepositoryServiceServer) CreateRepository(ctx context.Context, req *RepoCreateRequest) (*v1alpha1.Repository, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateRepository not implemented") } +func (*UnimplementedRepositoryServiceServer) CreateWriteRepository(ctx context.Context, req *RepoCreateRequest) (*v1alpha1.Repository, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateWriteRepository not implemented") +} func (*UnimplementedRepositoryServiceServer) Update(ctx context.Context, req *RepoUpdateRequest) (*v1alpha1.Repository, error) { return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") } func (*UnimplementedRepositoryServiceServer) UpdateRepository(ctx context.Context, req *RepoUpdateRequest) (*v1alpha1.Repository, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateRepository not implemented") } +func (*UnimplementedRepositoryServiceServer) UpdateWriteRepository(ctx context.Context, req *RepoUpdateRequest) (*v1alpha1.Repository, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateWriteRepository not implemented") +} func (*UnimplementedRepositoryServiceServer) Delete(ctx context.Context, req *RepoQuery) (*RepoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") } func (*UnimplementedRepositoryServiceServer) DeleteRepository(ctx context.Context, req *RepoQuery) (*RepoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteRepository not implemented") } +func (*UnimplementedRepositoryServiceServer) DeleteWriteRepository(ctx context.Context, req *RepoQuery) (*RepoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteWriteRepository not implemented") +} func (*UnimplementedRepositoryServiceServer) ValidateAccess(ctx context.Context, req *RepoAccessQuery) (*RepoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ValidateAccess not implemented") } +func (*UnimplementedRepositoryServiceServer) ValidateWriteAccess(ctx context.Context, req *RepoAccessQuery) (*RepoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateWriteAccess not implemented") +} func RegisterRepositoryServiceServer(s *grpc.Server, srv RepositoryServiceServer) { s.RegisterService(&_RepositoryService_serviceDesc, srv) @@ -1104,6 +1208,24 @@ func _RepositoryService_Get_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _RepositoryService_GetWrite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).GetWrite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/GetWrite", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).GetWrite(ctx, req.(*RepoQuery)) + } + return interceptor(ctx, in, info, handler) +} + func _RepositoryService_ListRepositories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoQuery) if err := dec(in); err != nil { @@ -1122,6 +1244,24 @@ func _RepositoryService_ListRepositories_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _RepositoryService_ListWriteRepositories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).ListWriteRepositories(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/ListWriteRepositories", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).ListWriteRepositories(ctx, req.(*RepoQuery)) + } + return interceptor(ctx, in, info, handler) +} + func _RepositoryService_ListRefs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoQuery) if err := dec(in); err != nil { @@ -1230,6 +1370,24 @@ func _RepositoryService_CreateRepository_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _RepositoryService_CreateWriteRepository_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoCreateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).CreateWriteRepository(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/CreateWriteRepository", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).CreateWriteRepository(ctx, req.(*RepoCreateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RepositoryService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoUpdateRequest) if err := dec(in); err != nil { @@ -1266,6 +1424,24 @@ func _RepositoryService_UpdateRepository_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _RepositoryService_UpdateWriteRepository_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoUpdateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).UpdateWriteRepository(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/UpdateWriteRepository", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).UpdateWriteRepository(ctx, req.(*RepoUpdateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RepositoryService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoQuery) if err := dec(in); err != nil { @@ -1302,6 +1478,24 @@ func _RepositoryService_DeleteRepository_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _RepositoryService_DeleteWriteRepository_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).DeleteWriteRepository(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/DeleteWriteRepository", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).DeleteWriteRepository(ctx, req.(*RepoQuery)) + } + return interceptor(ctx, in, info, handler) +} + func _RepositoryService_ValidateAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RepoAccessQuery) if err := dec(in); err != nil { @@ -1320,6 +1514,24 @@ func _RepositoryService_ValidateAccess_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _RepositoryService_ValidateWriteAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RepoAccessQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RepositoryServiceServer).ValidateWriteAccess(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/repository.RepositoryService/ValidateWriteAccess", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RepositoryServiceServer).ValidateWriteAccess(ctx, req.(*RepoAccessQuery)) + } + return interceptor(ctx, in, info, handler) +} + var _RepositoryService_serviceDesc = grpc.ServiceDesc{ ServiceName: "repository.RepositoryService", HandlerType: (*RepositoryServiceServer)(nil), @@ -1332,10 +1544,18 @@ var _RepositoryService_serviceDesc = grpc.ServiceDesc{ MethodName: "Get", Handler: _RepositoryService_Get_Handler, }, + { + MethodName: "GetWrite", + Handler: _RepositoryService_GetWrite_Handler, + }, { MethodName: "ListRepositories", Handler: _RepositoryService_ListRepositories_Handler, }, + { + MethodName: "ListWriteRepositories", + Handler: _RepositoryService_ListWriteRepositories_Handler, + }, { MethodName: "ListRefs", Handler: _RepositoryService_ListRefs_Handler, @@ -1360,6 +1580,10 @@ var _RepositoryService_serviceDesc = grpc.ServiceDesc{ MethodName: "CreateRepository", Handler: _RepositoryService_CreateRepository_Handler, }, + { + MethodName: "CreateWriteRepository", + Handler: _RepositoryService_CreateWriteRepository_Handler, + }, { MethodName: "Update", Handler: _RepositoryService_Update_Handler, @@ -1368,6 +1592,10 @@ var _RepositoryService_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateRepository", Handler: _RepositoryService_UpdateRepository_Handler, }, + { + MethodName: "UpdateWriteRepository", + Handler: _RepositoryService_UpdateWriteRepository_Handler, + }, { MethodName: "Delete", Handler: _RepositoryService_Delete_Handler, @@ -1376,10 +1604,18 @@ var _RepositoryService_serviceDesc = grpc.ServiceDesc{ MethodName: "DeleteRepository", Handler: _RepositoryService_DeleteRepository_Handler, }, + { + MethodName: "DeleteWriteRepository", + Handler: _RepositoryService_DeleteWriteRepository_Handler, + }, { MethodName: "ValidateAccess", Handler: _RepositoryService_ValidateAccess_Handler, }, + { + MethodName: "ValidateWriteAccess", + Handler: _RepositoryService_ValidateWriteAccess_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "server/repository/repository.proto", diff --git a/pkg/apiclient/repository/repository.pb.gw.go b/pkg/apiclient/repository/repository.pb.gw.go index da6a5a9eacb28..0a40de1928047 100644 --- a/pkg/apiclient/repository/repository.pb.gw.go +++ b/pkg/apiclient/repository/repository.pb.gw.go @@ -141,6 +141,78 @@ func local_request_RepositoryService_Get_0(ctx context.Context, marshaler runtim } +var ( + filter_RepositoryService_GetWrite_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_RepositoryService_GetWrite_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_GetWrite_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetWrite(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_GetWrite_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_GetWrite_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetWrite(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_RepositoryService_ListRepositories_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -177,6 +249,42 @@ func local_request_RepositoryService_ListRepositories_0(ctx context.Context, mar } +var ( + filter_RepositoryService_ListWriteRepositories_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_RepositoryService_ListWriteRepositories_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ListWriteRepositories_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListWriteRepositories(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_ListWriteRepositories_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ListWriteRepositories_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListWriteRepositories(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_RepositoryService_ListRefs_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -567,6 +675,58 @@ func local_request_RepositoryService_CreateRepository_0(ctx context.Context, mar } +var ( + filter_RepositoryService_CreateWriteRepository_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_RepositoryService_CreateWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCreateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_CreateWriteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateWriteRepository(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_CreateWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoCreateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_CreateWriteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateWriteRepository(ctx, &protoReq) + return msg, metadata, err + +} + func request_RepositoryService_Update_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RepoUpdateRequest var metadata runtime.ServerMetadata @@ -707,6 +867,76 @@ func local_request_RepositoryService_UpdateRepository_0(ctx context.Context, mar } +func request_RepositoryService_UpdateWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoUpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo.repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo.repo") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "repo.repo", val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo.repo", err) + } + + msg, err := client.UpdateWriteRepository(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_UpdateWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoUpdateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo.repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo.repo") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "repo.repo", val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo.repo", err) + } + + msg, err := server.UpdateWriteRepository(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_RepositoryService_Delete_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) @@ -808,19 +1038,179 @@ func request_RepositoryService_DeleteRepository_0(ctx context.Context, marshaler if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteRepository_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeleteRepository(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_DeleteRepository_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DeleteRepository(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_RepositoryService_DeleteWriteRepository_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_RepositoryService_DeleteWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteWriteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.DeleteWriteRepository(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_DeleteWriteRepository_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteWriteRepository_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.DeleteWriteRepository(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_RepositoryService_ValidateAccess_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} +) + +func request_RepositoryService_ValidateAccess_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoAccessQuery + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["repo"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo") + } + + protoReq.Repo, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateAccess_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ValidateAccess(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RepositoryService_ValidateAccess_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RepoAccessQuery + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Repo); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.DeleteRepository(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_RepositoryService_DeleteRepository_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq RepoQuery - var metadata runtime.ServerMetadata - var ( val string ok bool @@ -842,20 +1232,20 @@ func local_request_RepositoryService_DeleteRepository_0(ctx context.Context, mar if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_DeleteRepository_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateAccess_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.DeleteRepository(ctx, &protoReq) + msg, err := server.ValidateAccess(ctx, &protoReq) return msg, metadata, err } var ( - filter_RepositoryService_ValidateAccess_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} + filter_RepositoryService_ValidateWriteAccess_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} ) -func request_RepositoryService_ValidateAccess_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func request_RepositoryService_ValidateWriteAccess_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RepoAccessQuery var metadata runtime.ServerMetadata @@ -888,16 +1278,16 @@ func request_RepositoryService_ValidateAccess_0(ctx context.Context, marshaler r if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateAccess_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateWriteAccess_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ValidateAccess(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ValidateWriteAccess(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_RepositoryService_ValidateAccess_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func local_request_RepositoryService_ValidateWriteAccess_0(ctx context.Context, marshaler runtime.Marshaler, server RepositoryServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq RepoAccessQuery var metadata runtime.ServerMetadata @@ -930,11 +1320,11 @@ func local_request_RepositoryService_ValidateAccess_0(ctx context.Context, marsh if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateAccess_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RepositoryService_ValidateWriteAccess_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ValidateAccess(ctx, &protoReq) + msg, err := server.ValidateWriteAccess(ctx, &protoReq) return msg, metadata, err } @@ -991,6 +1381,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("GET", pattern_RepositoryService_GetWrite_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_GetWrite_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_GetWrite_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_RepositoryService_ListRepositories_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1014,6 +1427,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("GET", pattern_RepositoryService_ListWriteRepositories_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_ListWriteRepositories_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_ListWriteRepositories_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_RepositoryService_ListRefs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1152,6 +1588,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("POST", pattern_RepositoryService_CreateWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_CreateWriteRepository_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_CreateWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PUT", pattern_RepositoryService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1198,6 +1657,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("PUT", pattern_RepositoryService_UpdateWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_UpdateWriteRepository_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_UpdateWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_RepositoryService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1244,6 +1726,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("DELETE", pattern_RepositoryService_DeleteWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_DeleteWriteRepository_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_DeleteWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RepositoryService_ValidateAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1267,6 +1772,29 @@ func RegisterRepositoryServiceHandlerServer(ctx context.Context, mux *runtime.Se }) + mux.Handle("POST", pattern_RepositoryService_ValidateWriteAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RepositoryService_ValidateWriteAccess_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_ValidateWriteAccess_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1348,6 +1876,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("GET", pattern_RepositoryService_GetWrite_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_GetWrite_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_GetWrite_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_RepositoryService_ListRepositories_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1368,6 +1916,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("GET", pattern_RepositoryService_ListWriteRepositories_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_ListWriteRepositories_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_ListWriteRepositories_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_RepositoryService_ListRefs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1488,6 +2056,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("POST", pattern_RepositoryService_CreateWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_CreateWriteRepository_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_CreateWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PUT", pattern_RepositoryService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1528,6 +2116,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("PUT", pattern_RepositoryService_UpdateWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_UpdateWriteRepository_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_UpdateWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_RepositoryService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1568,6 +2176,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("DELETE", pattern_RepositoryService_DeleteWriteRepository_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_DeleteWriteRepository_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_DeleteWriteRepository_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RepositoryService_ValidateAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1588,6 +2216,26 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se }) + mux.Handle("POST", pattern_RepositoryService_ValidateWriteAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RepositoryService_ValidateWriteAccess_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_RepositoryService_ValidateWriteAccess_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1596,8 +2244,12 @@ var ( pattern_RepositoryService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_GetWrite_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "write-repositories", "repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_ListRepositories_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repositories"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_ListWriteRepositories_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "write-repositories"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_ListRefs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "repositories", "repo", "refs"}, "", runtime.AssumeColonVerbOpt(true))) pattern_RepositoryService_ListApps_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "repositories", "repo", "apps"}, "", runtime.AssumeColonVerbOpt(true))) @@ -1610,15 +2262,23 @@ var ( pattern_RepositoryService_CreateRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repositories"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_CreateWriteRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "write-repositories"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo.repo"}, "", runtime.AssumeColonVerbOpt(true))) pattern_RepositoryService_UpdateRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo.repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_UpdateWriteRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "write-repositories", "repo.repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo"}, "", runtime.AssumeColonVerbOpt(true))) pattern_RepositoryService_DeleteRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_DeleteWriteRepository_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "write-repositories", "repo"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_RepositoryService_ValidateAccess_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "repositories", "repo", "validate"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_RepositoryService_ValidateWriteAccess_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "write-repositories", "repo", "validate"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -1626,8 +2286,12 @@ var ( forward_RepositoryService_Get_0 = runtime.ForwardResponseMessage + forward_RepositoryService_GetWrite_0 = runtime.ForwardResponseMessage + forward_RepositoryService_ListRepositories_0 = runtime.ForwardResponseMessage + forward_RepositoryService_ListWriteRepositories_0 = runtime.ForwardResponseMessage + forward_RepositoryService_ListRefs_0 = runtime.ForwardResponseMessage forward_RepositoryService_ListApps_0 = runtime.ForwardResponseMessage @@ -1640,13 +2304,21 @@ var ( forward_RepositoryService_CreateRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_CreateWriteRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_Update_0 = runtime.ForwardResponseMessage forward_RepositoryService_UpdateRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_UpdateWriteRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_Delete_0 = runtime.ForwardResponseMessage forward_RepositoryService_DeleteRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_DeleteWriteRepository_0 = runtime.ForwardResponseMessage + forward_RepositoryService_ValidateAccess_0 = runtime.ForwardResponseMessage + + forward_RepositoryService_ValidateWriteAccess_0 = runtime.ForwardResponseMessage ) diff --git a/pkg/apiclient/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go index 3345756bd0aad..71bff2ca9edcf 100644 --- a/pkg/apiclient/settings/settings.pb.go +++ b/pkg/apiclient/settings/settings.pb.go @@ -102,6 +102,9 @@ type Settings struct { ControllerNamespace string `protobuf:"bytes,23,opt,name=controllerNamespace,proto3" json:"controllerNamespace,omitempty"` AppsInAnyNamespaceEnabled bool `protobuf:"varint,24,opt,name=appsInAnyNamespaceEnabled,proto3" json:"appsInAnyNamespaceEnabled,omitempty"` ImpersonationEnabled bool `protobuf:"varint,25,opt,name=impersonationEnabled,proto3" json:"impersonationEnabled,omitempty"` + InstallationID string `protobuf:"bytes,26,opt,name=installationID,proto3" json:"installationID,omitempty"` + AdditionalURLs []string `protobuf:"bytes,27,rep,name=additionalUrls,proto3" json:"additionalUrls,omitempty"` + HydratorEnabled bool `protobuf:"varint,28,opt,name=hydratorEnabled,proto3" json:"hydratorEnabled,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -315,6 +318,27 @@ func (m *Settings) GetImpersonationEnabled() bool { return false } +func (m *Settings) GetInstallationID() string { + if m != nil { + return m.InstallationID + } + return "" +} + +func (m *Settings) GetAdditionalURLs() []string { + if m != nil { + return m.AdditionalURLs + } + return nil +} + +func (m *Settings) GetHydratorEnabled() bool { + if m != nil { + return m.HydratorEnabled + } + return false +} + type GoogleAnalyticsConfig struct { TrackingID string `protobuf:"bytes,1,opt,name=trackingID,proto3" json:"trackingID,omitempty"` AnonymizeUsers bool `protobuf:"varint,2,opt,name=anonymizeUsers,proto3" json:"anonymizeUsers,omitempty"` @@ -748,84 +772,88 @@ func init() { func init() { proto.RegisterFile("server/settings/settings.proto", fileDescriptor_a480d494da040caa) } var fileDescriptor_a480d494da040caa = []byte{ - // 1232 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0x97, 0xeb, 0x34, 0xb1, 0x9f, 0x9b, 0x3a, 0x99, 0xa6, 0xe9, 0xd6, 0x2a, 0x89, 0xf1, 0xa1, - 0x32, 0x08, 0xd6, 0x8d, 0x2b, 0x04, 0xaa, 0xa8, 0xa0, 0xb6, 0xab, 0xd6, 0x34, 0x6d, 0xc3, 0xb4, - 0xe9, 0x81, 0x4b, 0x35, 0x59, 0x3f, 0xd6, 0x4b, 0xd6, 0x33, 0xab, 0x99, 0x59, 0x13, 0xf7, 0xc8, - 0x07, 0xe0, 0x02, 0x9f, 0x86, 0x3b, 0x82, 0x23, 0x12, 0xf7, 0x08, 0x59, 0x9c, 0xf8, 0x14, 0x68, - 0x67, 0xff, 0x64, 0xb3, 0x76, 0x0a, 0x52, 0x6f, 0x33, 0xbf, 0xdf, 0xfb, 0x37, 0x6f, 0xde, 0x9b, - 0x79, 0xb0, 0xa3, 0x50, 0x4e, 0x51, 0x76, 0x14, 0x6a, 0xed, 0x71, 0x57, 0x65, 0x0b, 0x3b, 0x90, - 0x42, 0x0b, 0xb2, 0xe6, 0xf8, 0xa1, 0xd2, 0x28, 0x1b, 0x5b, 0xae, 0x70, 0x85, 0xc1, 0x3a, 0xd1, - 0x2a, 0xa6, 0x1b, 0xb7, 0x5c, 0x21, 0x5c, 0x1f, 0x3b, 0x2c, 0xf0, 0x3a, 0x8c, 0x73, 0xa1, 0x99, - 0xf6, 0x04, 0x4f, 0x94, 0x1b, 0xfb, 0xae, 0xa7, 0xc7, 0xe1, 0x91, 0xed, 0x88, 0x49, 0x87, 0x49, - 0xa3, 0xfe, 0x9d, 0x59, 0x7c, 0xec, 0x8c, 0x3a, 0xd3, 0x6e, 0x27, 0x38, 0x76, 0x23, 0x4d, 0xd5, - 0x61, 0x41, 0xe0, 0x7b, 0x8e, 0xd1, 0xed, 0x4c, 0xf7, 0x98, 0x1f, 0x8c, 0xd9, 0x5e, 0xc7, 0x45, - 0x8e, 0x92, 0x69, 0x1c, 0x25, 0xd6, 0xbe, 0xfc, 0x0f, 0x6b, 0xc5, 0x93, 0x08, 0x6f, 0xe4, 0x74, - 0x1c, 0x9f, 0x79, 0x93, 0x24, 0x9e, 0x56, 0x1d, 0xd6, 0x5f, 0x24, 0xec, 0xd7, 0x21, 0xca, 0x59, - 0xeb, 0x9f, 0x1a, 0x54, 0x52, 0x84, 0xdc, 0x84, 0x72, 0x28, 0x7d, 0xab, 0xd4, 0x2c, 0xb5, 0xab, - 0xbd, 0xb5, 0xf9, 0xe9, 0x6e, 0xf9, 0x90, 0xee, 0xd3, 0x08, 0x23, 0x77, 0xa0, 0x3a, 0xc2, 0x93, - 0xbe, 0xe0, 0xdf, 0x7a, 0xae, 0x75, 0xa9, 0x59, 0x6a, 0xd7, 0xba, 0xc4, 0x4e, 0x32, 0x63, 0x0f, - 0x52, 0x86, 0x9e, 0x09, 0x91, 0x3e, 0x40, 0xe4, 0x3f, 0x51, 0x29, 0x1b, 0x95, 0x6b, 0x99, 0xca, - 0xf3, 0xe1, 0xa0, 0x1f, 0x53, 0xbd, 0xab, 0xf3, 0xd3, 0x5d, 0x38, 0xdb, 0xd3, 0x9c, 0x1a, 0x69, - 0x42, 0x8d, 0x05, 0xc1, 0x3e, 0x3b, 0x42, 0xff, 0x09, 0xce, 0xac, 0x95, 0x28, 0x32, 0x9a, 0x87, - 0xc8, 0x2b, 0xd8, 0x94, 0xa8, 0x44, 0x28, 0x1d, 0x7c, 0x3e, 0x45, 0x29, 0xbd, 0x11, 0x2a, 0xeb, - 0x72, 0xb3, 0xdc, 0xae, 0x75, 0xdb, 0x99, 0xb7, 0xf4, 0x84, 0x36, 0x2d, 0x8a, 0x3e, 0xe4, 0x5a, - 0xce, 0xe8, 0xa2, 0x09, 0x62, 0x03, 0x51, 0x9a, 0xe9, 0x50, 0xf5, 0xd8, 0xc8, 0xc5, 0x87, 0x9c, - 0x1d, 0xf9, 0x38, 0xb2, 0x56, 0x9b, 0xa5, 0x76, 0x85, 0x2e, 0x61, 0xc8, 0x63, 0xa8, 0xc7, 0x95, - 0xf0, 0x80, 0x33, 0x7f, 0xa6, 0x3d, 0x47, 0x59, 0x6b, 0xe6, 0xcc, 0x3b, 0x59, 0x14, 0x8f, 0xce, - 0xf3, 0xc9, 0x71, 0x8b, 0x6a, 0xe4, 0x0d, 0x6c, 0x1c, 0x87, 0x4a, 0x8b, 0x89, 0xf7, 0x06, 0x9f, - 0x07, 0xa6, 0x9a, 0xac, 0x8a, 0x31, 0xf5, 0xcc, 0x3e, 0x2b, 0x00, 0x3b, 0x2d, 0x00, 0xb3, 0x78, - 0xed, 0x8c, 0xec, 0x69, 0xd7, 0x0e, 0x8e, 0x5d, 0x3b, 0x2a, 0x27, 0x3b, 0x57, 0x4e, 0x76, 0x5a, - 0x4e, 0xf6, 0x93, 0x82, 0x55, 0xba, 0xe0, 0x87, 0xbc, 0x0f, 0x2b, 0x63, 0xf4, 0x03, 0xab, 0x6a, - 0xfc, 0xad, 0x67, 0xa1, 0x3f, 0x46, 0x3f, 0xa0, 0x86, 0x22, 0x1f, 0xc0, 0x5a, 0xe0, 0x87, 0xae, - 0xc7, 0x95, 0x05, 0x26, 0xcd, 0xf5, 0x4c, 0xea, 0xc0, 0xe0, 0x34, 0xe5, 0xa3, 0x1c, 0x86, 0x0a, - 0xe5, 0xbe, 0x88, 0x76, 0x03, 0x4f, 0xc5, 0x39, 0xac, 0xc5, 0x39, 0x5c, 0x64, 0xc8, 0x8f, 0x25, - 0xb8, 0xe1, 0x98, 0xac, 0x3c, 0x65, 0x9c, 0xb9, 0x38, 0x41, 0xae, 0x0f, 0x12, 0x5f, 0x57, 0x8c, - 0xaf, 0x97, 0xef, 0x96, 0x81, 0xfe, 0x52, 0xe3, 0xf4, 0x22, 0xa7, 0xe4, 0x23, 0xd8, 0xcc, 0x52, - 0xf4, 0x0a, 0xa5, 0x32, 0x77, 0xb1, 0xde, 0x2c, 0xb7, 0xab, 0x74, 0x91, 0x20, 0x0d, 0xa8, 0x84, - 0x5e, 0x5f, 0xa9, 0x43, 0xba, 0x6f, 0x5d, 0x35, 0x95, 0x9a, 0xed, 0x49, 0x1b, 0xea, 0xa1, 0xd7, - 0x63, 0x9c, 0xa3, 0xec, 0x0b, 0xae, 0x91, 0x6b, 0xab, 0x6e, 0x44, 0x8a, 0x70, 0x54, 0xf2, 0x29, - 0x14, 0x19, 0xda, 0x88, 0x4b, 0x3e, 0x07, 0x45, 0xb6, 0x02, 0xa6, 0xd4, 0xf7, 0x42, 0x8e, 0x0e, - 0x98, 0xd6, 0x28, 0xb9, 0xb5, 0x19, 0xdb, 0x2a, 0xc0, 0xe4, 0x36, 0x5c, 0xd5, 0x92, 0x39, 0xc7, - 0x1e, 0x77, 0x9f, 0xa2, 0x1e, 0x8b, 0x91, 0x45, 0x8c, 0x60, 0x01, 0x8d, 0xce, 0x99, 0x3a, 0x38, - 0x40, 0x39, 0x61, 0x3c, 0x8a, 0xef, 0x9a, 0xb9, 0xa7, 0x45, 0x82, 0x7c, 0x08, 0x1b, 0x19, 0x28, - 0x94, 0x17, 0xa5, 0xd8, 0xda, 0x32, 0x76, 0x17, 0xf0, 0x42, 0x1b, 0x51, 0x21, 0xf4, 0xa1, 0xf4, - 0xad, 0xeb, 0x46, 0x7a, 0x09, 0x13, 0x9d, 0x1e, 0x4f, 0xd0, 0x49, 0xfb, 0x6d, 0xdb, 0xc4, 0x90, - 0x87, 0xc8, 0x1d, 0xb8, 0xe6, 0x08, 0xae, 0xa5, 0xf0, 0x7d, 0x94, 0xcf, 0xd8, 0x04, 0x55, 0xc0, - 0x1c, 0xb4, 0x6e, 0x18, 0x93, 0xcb, 0x28, 0xf2, 0x39, 0xdc, 0x64, 0x41, 0xa0, 0x86, 0xfc, 0x01, - 0x9f, 0x65, 0x68, 0xea, 0xc1, 0x32, 0x1e, 0x2e, 0x16, 0x20, 0x5d, 0xd8, 0xf2, 0x26, 0x01, 0x4a, - 0x25, 0xb8, 0xa9, 0xa6, 0x54, 0xf1, 0xa6, 0x51, 0x5c, 0xca, 0x35, 0x7e, 0x2e, 0xc1, 0xf6, 0xf2, - 0xa7, 0x86, 0x6c, 0x40, 0xf9, 0x18, 0x67, 0xf1, 0x1b, 0x4b, 0xa3, 0x25, 0x19, 0xc1, 0xe5, 0x29, - 0xf3, 0x43, 0x4c, 0x9e, 0xd5, 0x77, 0x6c, 0xf2, 0xa2, 0x5b, 0x1a, 0x1b, 0xbf, 0x77, 0xe9, 0xb3, - 0x52, 0xeb, 0x35, 0x5c, 0x5f, 0xfa, 0x06, 0x91, 0x1d, 0x80, 0xb4, 0x22, 0x86, 0x83, 0x24, 0xb6, - 0x1c, 0x12, 0xd5, 0x11, 0xe3, 0x82, 0xcf, 0xa2, 0x72, 0x3f, 0x54, 0x28, 0x95, 0x89, 0xb5, 0x42, - 0x0b, 0x68, 0x6b, 0x00, 0x37, 0xd2, 0xa7, 0x36, 0x69, 0x21, 0x8a, 0x2a, 0x10, 0x5c, 0x61, 0xfe, - 0xd9, 0x28, 0xbd, 0xfd, 0xd9, 0x68, 0xfd, 0x52, 0x82, 0x95, 0xe8, 0xc1, 0x21, 0x16, 0xac, 0x39, - 0x63, 0x66, 0x2a, 0x26, 0x8e, 0x29, 0xdd, 0x46, 0xad, 0x16, 0x2d, 0x5f, 0xe2, 0x89, 0x36, 0xa1, - 0x54, 0x69, 0xb6, 0x27, 0xf7, 0x01, 0x8e, 0x3c, 0xce, 0xe4, 0xec, 0x50, 0xfa, 0xca, 0x2a, 0x1b, - 0x67, 0xef, 0x9d, 0x7b, 0xc9, 0xec, 0x5e, 0xc6, 0xc7, 0xef, 0x7f, 0x4e, 0xa1, 0x71, 0x1f, 0xea, - 0x05, 0x7a, 0xc9, 0x9d, 0x6d, 0xe5, 0xef, 0xac, 0x9a, 0xcf, 0xf1, 0x2d, 0x58, 0x8d, 0xcf, 0x43, - 0x08, 0xac, 0x70, 0x36, 0xc1, 0x44, 0xcd, 0xac, 0x5b, 0x5f, 0x40, 0x35, 0xfb, 0x2c, 0x49, 0x17, - 0xc0, 0x11, 0x9c, 0xa3, 0xa3, 0x85, 0x4c, 0xb3, 0x72, 0xf6, 0xa9, 0xf6, 0x53, 0x8a, 0xe6, 0xa4, - 0x5a, 0x77, 0xa1, 0x9a, 0x11, 0xcb, 0x3c, 0x44, 0x98, 0x9e, 0x05, 0x69, 0x60, 0x66, 0xdd, 0xfa, - 0xb5, 0x0c, 0xb9, 0x0f, 0x76, 0xa9, 0xda, 0x36, 0xac, 0x7a, 0x4a, 0x85, 0x28, 0x13, 0xc5, 0x64, - 0x47, 0xda, 0x50, 0x71, 0x7c, 0x0f, 0xb9, 0x1e, 0x0e, 0xcc, 0x1f, 0x5e, 0xed, 0x5d, 0x99, 0x9f, - 0xee, 0x56, 0xfa, 0x09, 0x46, 0x33, 0x96, 0xec, 0x41, 0xcd, 0xf1, 0xbd, 0x94, 0x88, 0xbf, 0xea, - 0x5e, 0x7d, 0x7e, 0xba, 0x5b, 0xeb, 0xef, 0x0f, 0x33, 0xf9, 0xbc, 0x4c, 0xe4, 0x54, 0x39, 0x22, - 0x48, 0x3e, 0xec, 0x2a, 0x4d, 0x76, 0xe4, 0x35, 0xac, 0x7b, 0xa3, 0x97, 0xe2, 0x18, 0x79, 0xdf, - 0x0c, 0x2f, 0xd6, 0xaa, 0xc9, 0xcd, 0xed, 0x25, 0xd3, 0x83, 0x3d, 0xcc, 0x0b, 0x9a, 0xeb, 0xea, - 0x6d, 0xce, 0x4f, 0x77, 0xd7, 0x87, 0x83, 0x1c, 0x4e, 0xcf, 0xdb, 0x23, 0xf7, 0xc0, 0x42, 0xd3, - 0xaa, 0x07, 0x4f, 0xfa, 0x0f, 0x1f, 0x84, 0x7a, 0x8c, 0x5c, 0x27, 0x9d, 0x64, 0x7e, 0xed, 0x0a, - 0xbd, 0x90, 0x6f, 0xcc, 0x80, 0x2c, 0xfa, 0x5c, 0x52, 0x22, 0x4f, 0xcf, 0xb7, 0xf5, 0xa7, 0x6f, - 0x6d, 0xeb, 0x78, 0x72, 0xb3, 0xb3, 0xd1, 0x33, 0x1a, 0x81, 0x6c, 0x63, 0x3f, 0x57, 0x5b, 0xdd, - 0xdf, 0x4a, 0x50, 0x4f, 0xfb, 0xeb, 0x05, 0xca, 0xa9, 0xe7, 0x20, 0xf9, 0x0a, 0xca, 0x8f, 0x50, - 0x93, 0xed, 0x85, 0x59, 0xc7, 0xcc, 0x77, 0x8d, 0xcd, 0x05, 0xbc, 0x65, 0xfd, 0xf0, 0xe7, 0xdf, - 0x3f, 0x5d, 0x22, 0x64, 0xc3, 0xcc, 0xac, 0xd3, 0xbd, 0x6c, 0x5e, 0x24, 0x63, 0x80, 0x47, 0x98, - 0x7d, 0x7e, 0x17, 0x99, 0x6c, 0x2e, 0xe0, 0x85, 0x5e, 0x6f, 0x35, 0x8d, 0x87, 0x06, 0xb1, 0x8a, - 0x1e, 0x3a, 0x49, 0x8b, 0xf7, 0xfa, 0xbf, 0xcf, 0x77, 0x4a, 0x7f, 0xcc, 0x77, 0x4a, 0x7f, 0xcd, - 0x77, 0x4a, 0xdf, 0x7c, 0xf2, 0xff, 0xa6, 0xe4, 0xb8, 0xd4, 0x32, 0x63, 0x47, 0xab, 0x66, 0xa6, - 0xbd, 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8d, 0xd6, 0x25, 0xb7, 0xc2, 0x0b, 0x00, 0x00, + // 1293 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcd, 0x6e, 0x1b, 0xb7, + 0x16, 0xc6, 0x44, 0x8e, 0x2d, 0x1d, 0xc7, 0x96, 0xcd, 0x38, 0xce, 0x44, 0x37, 0xd7, 0xd6, 0xd5, + 0x22, 0xd0, 0xbd, 0xb8, 0x1d, 0xc5, 0x0a, 0x8a, 0x16, 0x41, 0x83, 0xd6, 0x92, 0x82, 0x44, 0x8d, + 0x92, 0xb8, 0x4c, 0x9c, 0x45, 0x37, 0x01, 0x3d, 0xc3, 0x8e, 0xa6, 0x1e, 0x91, 0x03, 0x92, 0xa3, + 0x46, 0x59, 0xf6, 0x01, 0xba, 0x69, 0x9f, 0xa6, 0xfb, 0xa2, 0x5d, 0x16, 0xe8, 0xde, 0x28, 0x84, + 0x3e, 0x44, 0x97, 0x05, 0x39, 0x3f, 0x1e, 0x8f, 0xe4, 0xb4, 0x40, 0x76, 0xe4, 0xf7, 0x9d, 0x3f, + 0x1e, 0x9e, 0x43, 0x1e, 0xd8, 0x93, 0x54, 0x4c, 0xa9, 0xe8, 0x48, 0xaa, 0x54, 0xc0, 0x7c, 0x99, + 0x2f, 0x9c, 0x48, 0x70, 0xc5, 0xd1, 0x9a, 0x1b, 0xc6, 0x52, 0x51, 0xd1, 0xd8, 0xf1, 0xb9, 0xcf, + 0x0d, 0xd6, 0xd1, 0xab, 0x84, 0x6e, 0xdc, 0xf6, 0x39, 0xf7, 0x43, 0xda, 0x21, 0x51, 0xd0, 0x21, + 0x8c, 0x71, 0x45, 0x54, 0xc0, 0x59, 0xaa, 0xdc, 0x18, 0xf9, 0x81, 0x1a, 0xc7, 0x27, 0x8e, 0xcb, + 0x27, 0x1d, 0x22, 0x8c, 0xfa, 0xd7, 0x66, 0xf1, 0x81, 0xeb, 0x75, 0xa6, 0xdd, 0x4e, 0x74, 0xea, + 0x6b, 0x4d, 0xd9, 0x21, 0x51, 0x14, 0x06, 0xae, 0xd1, 0xed, 0x4c, 0x0f, 0x48, 0x18, 0x8d, 0xc9, + 0x41, 0xc7, 0xa7, 0x8c, 0x0a, 0xa2, 0xa8, 0x97, 0x5a, 0xfb, 0xec, 0x6f, 0xac, 0x95, 0x4f, 0xc2, + 0x03, 0xcf, 0xed, 0xb8, 0x21, 0x09, 0x26, 0x69, 0x3c, 0xad, 0x3a, 0x6c, 0xbc, 0x48, 0xd9, 0x2f, + 0x62, 0x2a, 0x66, 0xad, 0x3f, 0xaf, 0x41, 0x35, 0x43, 0xd0, 0x2d, 0xa8, 0xc4, 0x22, 0xb4, 0xad, + 0xa6, 0xd5, 0xae, 0xf5, 0xd6, 0xe6, 0x67, 0xfb, 0x95, 0x63, 0x3c, 0xc2, 0x1a, 0x43, 0x77, 0xa1, + 0xe6, 0xd1, 0x37, 0x7d, 0xce, 0xbe, 0x0a, 0x7c, 0xfb, 0x4a, 0xd3, 0x6a, 0xaf, 0x77, 0x91, 0x93, + 0x66, 0xc6, 0x19, 0x64, 0x0c, 0x3e, 0x17, 0x42, 0x7d, 0x00, 0xed, 0x3f, 0x55, 0xa9, 0x18, 0x95, + 0xeb, 0xb9, 0xca, 0xf3, 0xe1, 0xa0, 0x9f, 0x50, 0xbd, 0xcd, 0xf9, 0xd9, 0x3e, 0x9c, 0xef, 0x71, + 0x41, 0x0d, 0x35, 0x61, 0x9d, 0x44, 0xd1, 0x88, 0x9c, 0xd0, 0xf0, 0x09, 0x9d, 0xd9, 0x2b, 0x3a, + 0x32, 0x5c, 0x84, 0xd0, 0x2b, 0xd8, 0x16, 0x54, 0xf2, 0x58, 0xb8, 0xf4, 0xf9, 0x94, 0x0a, 0x11, + 0x78, 0x54, 0xda, 0x57, 0x9b, 0x95, 0xf6, 0x7a, 0xb7, 0x9d, 0x7b, 0xcb, 0x4e, 0xe8, 0xe0, 0xb2, + 0xe8, 0x43, 0xa6, 0xc4, 0x0c, 0x2f, 0x9a, 0x40, 0x0e, 0x20, 0xa9, 0x88, 0x8a, 0x65, 0x8f, 0x78, + 0x3e, 0x7d, 0xc8, 0xc8, 0x49, 0x48, 0x3d, 0x7b, 0xb5, 0x69, 0xb5, 0xab, 0x78, 0x09, 0x83, 0x1e, + 0x43, 0x3d, 0xa9, 0x84, 0x43, 0x46, 0xc2, 0x99, 0x0a, 0x5c, 0x69, 0xaf, 0x99, 0x33, 0xef, 0xe5, + 0x51, 0x3c, 0xba, 0xc8, 0xa7, 0xc7, 0x2d, 0xab, 0xa1, 0xb7, 0xb0, 0x75, 0x1a, 0x4b, 0xc5, 0x27, + 0xc1, 0x5b, 0xfa, 0x3c, 0x32, 0xd5, 0x64, 0x57, 0x8d, 0xa9, 0x67, 0xce, 0x79, 0x01, 0x38, 0x59, + 0x01, 0x98, 0xc5, 0x6b, 0xd7, 0x73, 0xa6, 0x5d, 0x27, 0x3a, 0xf5, 0x1d, 0x5d, 0x4e, 0x4e, 0xa1, + 0x9c, 0x9c, 0xac, 0x9c, 0x9c, 0x27, 0x25, 0xab, 0x78, 0xc1, 0x0f, 0xfa, 0x0f, 0xac, 0x8c, 0x69, + 0x18, 0xd9, 0x35, 0xe3, 0x6f, 0x23, 0x0f, 0xfd, 0x31, 0x0d, 0x23, 0x6c, 0x28, 0xf4, 0x5f, 0x58, + 0x8b, 0xc2, 0xd8, 0x0f, 0x98, 0xb4, 0xc1, 0xa4, 0xb9, 0x9e, 0x4b, 0x1d, 0x19, 0x1c, 0x67, 0xbc, + 0xce, 0x61, 0x2c, 0xa9, 0x18, 0x71, 0xbd, 0x1b, 0x04, 0x32, 0xc9, 0xe1, 0x7a, 0x92, 0xc3, 0x45, + 0x06, 0x7d, 0x67, 0xc1, 0x4d, 0xd7, 0x64, 0xe5, 0x29, 0x61, 0xc4, 0xa7, 0x13, 0xca, 0xd4, 0x51, + 0xea, 0xeb, 0x9a, 0xf1, 0xf5, 0xf2, 0xfd, 0x32, 0xd0, 0x5f, 0x6a, 0x1c, 0x5f, 0xe6, 0x14, 0xfd, + 0x1f, 0xb6, 0xf3, 0x14, 0xbd, 0xa2, 0x42, 0x9a, 0xbb, 0xd8, 0x68, 0x56, 0xda, 0x35, 0xbc, 0x48, + 0xa0, 0x06, 0x54, 0xe3, 0xa0, 0x2f, 0xe5, 0x31, 0x1e, 0xd9, 0x9b, 0xa6, 0x52, 0xf3, 0x3d, 0x6a, + 0x43, 0x3d, 0x0e, 0x7a, 0x84, 0x31, 0x2a, 0xfa, 0x9c, 0x29, 0xca, 0x94, 0x5d, 0x37, 0x22, 0x65, + 0x58, 0x97, 0x7c, 0x06, 0x69, 0x43, 0x5b, 0x49, 0xc9, 0x17, 0x20, 0x6d, 0x2b, 0x22, 0x52, 0x7e, + 0xc3, 0x85, 0x77, 0x44, 0x94, 0xa2, 0x82, 0xd9, 0xdb, 0x89, 0xad, 0x12, 0x8c, 0xee, 0xc0, 0xa6, + 0x12, 0xc4, 0x3d, 0x0d, 0x98, 0xff, 0x94, 0xaa, 0x31, 0xf7, 0x6c, 0x64, 0x04, 0x4b, 0xa8, 0x3e, + 0x67, 0xe6, 0xe0, 0x88, 0x8a, 0x09, 0x61, 0x3a, 0xbe, 0xeb, 0xe6, 0x9e, 0x16, 0x09, 0xf4, 0x3f, + 0xd8, 0xca, 0x41, 0x2e, 0x03, 0x9d, 0x62, 0x7b, 0xc7, 0xd8, 0x5d, 0xc0, 0x4b, 0x6d, 0x84, 0x39, + 0x57, 0xc7, 0x22, 0xb4, 0x6f, 0x18, 0xe9, 0x25, 0x8c, 0x3e, 0x3d, 0x7d, 0x43, 0xdd, 0xac, 0xdf, + 0x76, 0x4d, 0x0c, 0x45, 0x08, 0xdd, 0x85, 0xeb, 0x2e, 0x67, 0x4a, 0xf0, 0x30, 0xa4, 0xe2, 0x19, + 0x99, 0x50, 0x19, 0x11, 0x97, 0xda, 0x37, 0x8d, 0xc9, 0x65, 0x14, 0xfa, 0x04, 0x6e, 0x91, 0x28, + 0x92, 0x43, 0x76, 0xc8, 0x66, 0x39, 0x9a, 0x79, 0xb0, 0x8d, 0x87, 0xcb, 0x05, 0x50, 0x17, 0x76, + 0x82, 0x49, 0x44, 0x85, 0xe4, 0xcc, 0x54, 0x53, 0xa6, 0x78, 0xcb, 0x28, 0x2e, 0xe5, 0x74, 0xde, + 0x03, 0x26, 0x15, 0x09, 0x43, 0x03, 0x0f, 0x07, 0x76, 0x23, 0xc9, 0xfb, 0x45, 0x14, 0xdd, 0x87, + 0x4d, 0xe2, 0x79, 0x26, 0x53, 0x24, 0x3c, 0x16, 0xa1, 0xb4, 0xff, 0xa5, 0x8b, 0xab, 0x87, 0xe6, + 0x67, 0xfb, 0x9b, 0x87, 0xe7, 0x0c, 0x1e, 0x49, 0x5c, 0x92, 0xd4, 0x55, 0x30, 0x9e, 0x79, 0x82, + 0x28, 0x2e, 0xb2, 0x90, 0x6e, 0x9b, 0x90, 0xca, 0x70, 0xe3, 0x07, 0x0b, 0x76, 0x97, 0x3f, 0x7c, + 0x68, 0x0b, 0x2a, 0xa7, 0x74, 0x96, 0xbc, 0xf8, 0x58, 0x2f, 0x91, 0x07, 0x57, 0xa7, 0x24, 0x8c, + 0x69, 0xfa, 0xc8, 0xbf, 0xe7, 0x93, 0x53, 0x76, 0x8b, 0x13, 0xe3, 0xf7, 0xaf, 0x7c, 0x6c, 0xb5, + 0x5e, 0xc3, 0x8d, 0xa5, 0x2f, 0x22, 0xda, 0x03, 0xc8, 0xea, 0x73, 0x38, 0x48, 0x63, 0x2b, 0x20, + 0x3a, 0xbb, 0x84, 0x71, 0x36, 0xd3, 0xcd, 0x77, 0x2c, 0xa9, 0x90, 0x26, 0xd6, 0x2a, 0x2e, 0xa1, + 0xad, 0x01, 0xdc, 0xcc, 0x1e, 0xfe, 0xb4, 0xa1, 0x31, 0x95, 0x11, 0x67, 0x92, 0x16, 0x1f, 0x31, + 0xeb, 0xdd, 0x8f, 0x58, 0xeb, 0x47, 0x0b, 0x56, 0xf4, 0xf3, 0x87, 0x6c, 0x58, 0x73, 0xc7, 0xc4, + 0xd4, 0x6f, 0x12, 0x53, 0xb6, 0xd5, 0x8d, 0xaf, 0x97, 0x2f, 0xe9, 0x1b, 0x65, 0x42, 0xa9, 0xe1, + 0x7c, 0x8f, 0x1e, 0x00, 0x9c, 0x04, 0x8c, 0x88, 0x99, 0xb9, 0xde, 0x8a, 0x71, 0xf6, 0xef, 0x0b, + 0xef, 0xaa, 0xd3, 0xcb, 0xf9, 0xe4, 0x37, 0x2a, 0x28, 0x34, 0x1e, 0x40, 0xbd, 0x44, 0x2f, 0xb9, + 0xb3, 0x9d, 0xe2, 0x9d, 0xd5, 0x8a, 0x39, 0xbe, 0x0d, 0xab, 0xc9, 0x79, 0x10, 0x82, 0x15, 0x46, + 0x26, 0x34, 0x55, 0x33, 0xeb, 0xd6, 0xa7, 0x50, 0xcb, 0xbf, 0x6e, 0xd4, 0x05, 0x70, 0x39, 0x63, + 0xd4, 0x55, 0x5c, 0x64, 0x59, 0x39, 0xff, 0xe2, 0xfb, 0x19, 0x85, 0x0b, 0x52, 0xad, 0x7b, 0x50, + 0xcb, 0x89, 0x65, 0x1e, 0x34, 0xa6, 0x66, 0x51, 0x16, 0x98, 0x59, 0xb7, 0x7e, 0xaa, 0x40, 0xe1, + 0xbb, 0x5f, 0xaa, 0xb6, 0x0b, 0xab, 0x81, 0x94, 0x31, 0x15, 0xa9, 0x62, 0xba, 0x43, 0x6d, 0xa8, + 0xba, 0x61, 0x40, 0x99, 0x1a, 0x0e, 0xcc, 0x44, 0x51, 0xeb, 0x5d, 0x9b, 0x9f, 0xed, 0x57, 0xfb, + 0x29, 0x86, 0x73, 0x16, 0x1d, 0xc0, 0xba, 0x1b, 0x06, 0x19, 0x91, 0x0c, 0x0e, 0xbd, 0xfa, 0xfc, + 0x6c, 0x7f, 0xbd, 0x3f, 0x1a, 0xe6, 0xf2, 0x45, 0x19, 0xed, 0x54, 0xba, 0x3c, 0x4a, 0xc7, 0x87, + 0x1a, 0x4e, 0x77, 0xe8, 0x35, 0x6c, 0x04, 0xde, 0x4b, 0x7e, 0x4a, 0x59, 0xdf, 0x8c, 0x52, 0xf6, + 0xaa, 0xc9, 0xcd, 0x9d, 0x25, 0xb3, 0x8c, 0x33, 0x2c, 0x0a, 0x9a, 0xeb, 0xea, 0x6d, 0xcf, 0xcf, + 0xf6, 0x37, 0x86, 0x83, 0x02, 0x8e, 0x2f, 0xda, 0x43, 0xf7, 0xc1, 0xa6, 0xa6, 0x55, 0x8f, 0x9e, + 0xf4, 0x1f, 0x1e, 0xc6, 0x6a, 0x4c, 0x99, 0x4a, 0x3b, 0xc9, 0xcc, 0x10, 0x55, 0x7c, 0x29, 0xdf, + 0x98, 0x01, 0x5a, 0xf4, 0xb9, 0xa4, 0x44, 0x9e, 0x5e, 0x6c, 0xeb, 0x8f, 0xde, 0xd9, 0xd6, 0xc9, + 0x1c, 0xe9, 0xe4, 0x83, 0xb0, 0x1e, 0xc8, 0x1c, 0x63, 0xbf, 0x50, 0x5b, 0xdd, 0x9f, 0x2d, 0xa8, + 0x67, 0xfd, 0xf5, 0x82, 0x8a, 0x69, 0xe0, 0x52, 0xf4, 0x39, 0x54, 0x1e, 0x51, 0x85, 0x76, 0x17, + 0x26, 0x2f, 0x33, 0x6d, 0x36, 0xb6, 0x17, 0xf0, 0x96, 0xfd, 0xed, 0x6f, 0x7f, 0x7c, 0x7f, 0x05, + 0xa1, 0x2d, 0x33, 0x41, 0x4f, 0x0f, 0xf2, 0xe9, 0x15, 0x8d, 0x01, 0x1e, 0xd1, 0xfc, 0x2b, 0xbe, + 0xcc, 0x64, 0x73, 0x01, 0x2f, 0xf5, 0x7a, 0xab, 0x69, 0x3c, 0x34, 0x90, 0x5d, 0xf6, 0xd0, 0x49, + 0x5b, 0xbc, 0xd7, 0xff, 0x65, 0xbe, 0x67, 0xfd, 0x3a, 0xdf, 0xb3, 0x7e, 0x9f, 0xef, 0x59, 0x5f, + 0x7e, 0xf8, 0xcf, 0x66, 0xf6, 0xa4, 0xd4, 0x72, 0x63, 0x27, 0xab, 0x66, 0xc2, 0xbe, 0xf7, 0x57, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x57, 0xdb, 0xcf, 0xcf, 0x50, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -999,6 +1027,38 @@ func (m *Settings) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.HydratorEnabled { + i-- + if m.HydratorEnabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + } + if len(m.AdditionalURLs) > 0 { + for iNdEx := len(m.AdditionalURLs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AdditionalURLs[iNdEx]) + copy(dAtA[i:], m.AdditionalURLs[iNdEx]) + i = encodeVarintSettings(dAtA, i, uint64(len(m.AdditionalURLs[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xda + } + } + if len(m.InstallationID) > 0 { + i -= len(m.InstallationID) + copy(dAtA[i:], m.InstallationID) + i = encodeVarintSettings(dAtA, i, uint64(len(m.InstallationID))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } if m.ImpersonationEnabled { i-- if m.ImpersonationEnabled { @@ -1774,6 +1834,19 @@ func (m *Settings) Size() (n int) { if m.ImpersonationEnabled { n += 3 } + l = len(m.InstallationID) + if l > 0 { + n += 2 + l + sovSettings(uint64(l)) + } + if len(m.AdditionalURLs) > 0 { + for _, s := range m.AdditionalURLs { + l = len(s) + n += 2 + l + sovSettings(uint64(l)) + } + } + if m.HydratorEnabled { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2884,6 +2957,90 @@ func (m *Settings) Unmarshal(dAtA []byte) error { } } m.ImpersonationEnabled = bool(v != 0) + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstallationID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettings + } + 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 ErrInvalidLengthSettings + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettings + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InstallationID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 27: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AdditionalURLs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettings + } + 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 ErrInvalidLengthSettings + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettings + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AdditionalURLs = append(m.AdditionalURLs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HydratorEnabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettings + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.HydratorEnabled = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSettings(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/app_project_types.go b/pkg/apis/application/v1alpha1/app_project_types.go index b888cd37391b3..436e578548e3d 100644 --- a/pkg/apis/application/v1alpha1/app_project_types.go +++ b/pkg/apis/application/v1alpha1/app_project_types.go @@ -6,15 +6,22 @@ import ( "strconv" "strings" - "github.com/argoproj/argo-cd/v2/util/git" - "github.com/argoproj/argo-cd/v2/util/glob" - + globutil "github.com/gobwas/glob" "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/argoproj/argo-cd/v2/util/git" + "github.com/argoproj/argo-cd/v2/util/glob" +) + +const ( + // serviceAccountDisallowedCharSet contains the characters that are not allowed to be present + // in a DefaultServiceAccount configured for a DestinationServiceAccount + serviceAccountDisallowedCharSet = "!*[]{}\\/" ) type ErrApplicationNotAllowedToUseProject struct { @@ -267,12 +274,27 @@ func (p *AppProject) ValidateProject() error { destServiceAccts := make(map[string]bool) for _, destServiceAcct := range p.Spec.DestinationServiceAccounts { - if destServiceAcct.Server == "!*" { - return status.Errorf(codes.InvalidArgument, "server has an invalid format, '!*'") + if strings.Contains(destServiceAcct.Server, "!") { + return status.Errorf(codes.InvalidArgument, "server has an invalid format, '%s'", destServiceAcct.Server) } - if destServiceAcct.Namespace == "!*" { - return status.Errorf(codes.InvalidArgument, "namespace has an invalid format, '!*'") + if strings.Contains(destServiceAcct.Namespace, "!") { + return status.Errorf(codes.InvalidArgument, "namespace has an invalid format, '%s'", destServiceAcct.Namespace) + } + + if strings.Trim(destServiceAcct.DefaultServiceAccount, " ") == "" || + strings.ContainsAny(destServiceAcct.DefaultServiceAccount, serviceAccountDisallowedCharSet) { + return status.Errorf(codes.InvalidArgument, "defaultServiceAccount has an invalid format, '%s'", destServiceAcct.DefaultServiceAccount) + } + + _, err := globutil.Compile(destServiceAcct.Server) + if err != nil { + return status.Errorf(codes.InvalidArgument, "server has an invalid format, '%s'", destServiceAcct.Server) + } + + _, err = globutil.Compile(destServiceAcct.Namespace) + if err != nil { + return status.Errorf(codes.InvalidArgument, "namespace has an invalid format, '%s'", destServiceAcct.Namespace) } key := fmt.Sprintf("%s/%s", destServiceAcct.Server, destServiceAcct.Namespace) @@ -461,7 +483,6 @@ func (proj AppProject) IsDestinationPermitted(dst ApplicationDestination, projec func (proj AppProject) isDestinationMatched(dst ApplicationDestination) bool { anyDestinationMatched := false - noDenyDestinationsMatched := true for _, item := range proj.Spec.Destinations { dstNameMatched := dst.Name != "" && globMatch(item.Name, dst.Name, true) @@ -471,12 +492,14 @@ func (proj AppProject) isDestinationMatched(dst ApplicationDestination) bool { matched := (dstServerMatched || dstNameMatched) && dstNamespaceMatched if matched { anyDestinationMatched = true - } else if ((!dstNameMatched && isDenyPattern(item.Name)) || (!dstServerMatched && isDenyPattern(item.Server))) || (!dstNamespaceMatched && isDenyPattern(item.Namespace)) { - noDenyDestinationsMatched = false + } else if (!dstNameMatched && isDenyPattern(item.Name)) || (!dstServerMatched && isDenyPattern(item.Server)) && dstNamespaceMatched { + return false + } else if !dstNamespaceMatched && isDenyPattern(item.Namespace) && dstServerMatched { + return false } } - return anyDestinationMatched && noDenyDestinationsMatched + return anyDestinationMatched } func isDenyPattern(pattern string) bool { diff --git a/pkg/apis/application/v1alpha1/application_annotations.go b/pkg/apis/application/v1alpha1/application_annotations.go index 2c5e4ac3f8b7c..6395b5dbee494 100644 --- a/pkg/apis/application/v1alpha1/application_annotations.go +++ b/pkg/apis/application/v1alpha1/application_annotations.go @@ -4,6 +4,8 @@ const ( // AnnotationKeyRefresh is the annotation key which indicates that app needs to be refreshed. Removed by application controller after app is refreshed. // Might take values 'normal'/'hard'. Value 'hard' means manifest cache and target cluster state cache should be invalidated before refresh. AnnotationKeyRefresh string = "argocd.argoproj.io/refresh" + // AnnotationKeyHydrate is the annotation key which indicates that app needs to be hydrated. Removed by application controller after app is hydrated. + AnnotationKeyHydrate string = "argocd.argoproj.io/hydrate" // AnnotationKeyManifestGeneratePaths is an annotation that contains a list of semicolon-separated paths in the // manifests repository that affects the manifest generation. Paths might be either relative or absolute. The diff --git a/pkg/apis/application/v1alpha1/applicationset_types.go b/pkg/apis/application/v1alpha1/applicationset_types.go index d4446130c7026..16f9eeecd5d85 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types.go +++ b/pkg/apis/application/v1alpha1/applicationset_types.go @@ -379,6 +379,9 @@ type ClusterGenerator struct { // Values contains key/value pairs which are passed directly as parameters to the template Values map[string]string `json:"values,omitempty" protobuf:"bytes,3,name=values"` + + // returns the clusters a single 'clusters' value in the template + FlatList bool `json:"flatList,omitempty" protobuf:"bytes,4,name=flatList"` } // DuckType defines a generator to match against clusters registered with ArgoCD. diff --git a/pkg/apis/application/v1alpha1/applicationset_types_test.go b/pkg/apis/application/v1alpha1/applicationset_types_test.go index 867024578f76e..cb61167b2ebf1 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types_test.go +++ b/pkg/apis/application/v1alpha1/applicationset_types_test.go @@ -101,6 +101,7 @@ func TestApplicationSetSetConditions(t *testing.T) { testAppSetCond(ApplicationSetConditionResourcesUpToDate, "bar", tenMinsAgo, ApplicationSetConditionStatusTrue, ApplicationSetReasonApplicationSetUpToDate), }, validate: func(t *testing.T, a *ApplicationSet) { + t.Helper() assert.Equal(t, fiveMinsAgo, a.Status.Conditions[0].LastTransitionTime) assert.Equal(t, tenMinsAgo, a.Status.Conditions[1].LastTransitionTime) }, @@ -120,6 +121,7 @@ func TestApplicationSetSetConditions(t *testing.T) { testAppSetCond(ApplicationSetConditionResourcesUpToDate, "bar", nil, ApplicationSetConditionStatusFalse, ApplicationSetReasonApplicationSetUpToDate), }, validate: func(t *testing.T, a *ApplicationSet) { + t.Helper() // SetConditions should add timestamps for new conditions. assert.True(t, a.Status.Conditions[0].LastTransitionTime.Time.After(fiveMinsAgo.Time)) assert.True(t, a.Status.Conditions[1].LastTransitionTime.Time.After(fiveMinsAgo.Time)) @@ -141,6 +143,7 @@ func TestApplicationSetSetConditions(t *testing.T) { testAppSetCond(ApplicationSetConditionResourcesUpToDate, "bar", tenMinsAgo, ApplicationSetConditionStatusTrue, ApplicationSetReasonApplicationSetUpToDate), }, validate: func(t *testing.T, a *ApplicationSet) { + t.Helper() assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[0].LastTransitionTime.Time) }, }, @@ -161,6 +164,7 @@ func TestApplicationSetSetConditions(t *testing.T) { } func assertAppSetConditions(t *testing.T, expected []ApplicationSetCondition, actual []ApplicationSetCondition) { + t.Helper() assert.Equal(t, len(expected), len(actual)) for i := range expected { assert.Equal(t, expected[i].Type, actual[i].Type) diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 5fc96609621ca..bdb2368203f3b 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -1665,10 +1665,38 @@ func (m *ConnectionState) XXX_DiscardUnknown() { var xxx_messageInfo_ConnectionState proto.InternalMessageInfo +func (m *DrySource) Reset() { *m = DrySource{} } +func (*DrySource) ProtoMessage() {} +func (*DrySource) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{58} +} +func (m *DrySource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DrySource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DrySource) XXX_Merge(src proto.Message) { + xxx_messageInfo_DrySource.Merge(m, src) +} +func (m *DrySource) XXX_Size() int { + return m.Size() +} +func (m *DrySource) XXX_DiscardUnknown() { + xxx_messageInfo_DrySource.DiscardUnknown(m) +} + +var xxx_messageInfo_DrySource proto.InternalMessageInfo + func (m *DuckTypeGenerator) Reset() { *m = DuckTypeGenerator{} } func (*DuckTypeGenerator) ProtoMessage() {} func (*DuckTypeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{58} + return fileDescriptor_030104ce3b95bcac, []int{59} } func (m *DuckTypeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1696,7 +1724,7 @@ var xxx_messageInfo_DuckTypeGenerator proto.InternalMessageInfo func (m *EnvEntry) Reset() { *m = EnvEntry{} } func (*EnvEntry) ProtoMessage() {} func (*EnvEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{59} + return fileDescriptor_030104ce3b95bcac, []int{60} } func (m *EnvEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1724,7 +1752,7 @@ var xxx_messageInfo_EnvEntry proto.InternalMessageInfo func (m *ErrApplicationNotAllowedToUseProject) Reset() { *m = ErrApplicationNotAllowedToUseProject{} } func (*ErrApplicationNotAllowedToUseProject) ProtoMessage() {} func (*ErrApplicationNotAllowedToUseProject) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{60} + return fileDescriptor_030104ce3b95bcac, []int{61} } func (m *ErrApplicationNotAllowedToUseProject) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1752,7 +1780,7 @@ var xxx_messageInfo_ErrApplicationNotAllowedToUseProject proto.InternalMessageIn func (m *ExecProviderConfig) Reset() { *m = ExecProviderConfig{} } func (*ExecProviderConfig) ProtoMessage() {} func (*ExecProviderConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{61} + return fileDescriptor_030104ce3b95bcac, []int{62} } func (m *ExecProviderConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1780,7 +1808,7 @@ var xxx_messageInfo_ExecProviderConfig proto.InternalMessageInfo func (m *GitDirectoryGeneratorItem) Reset() { *m = GitDirectoryGeneratorItem{} } func (*GitDirectoryGeneratorItem) ProtoMessage() {} func (*GitDirectoryGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{62} + return fileDescriptor_030104ce3b95bcac, []int{63} } func (m *GitDirectoryGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1808,7 +1836,7 @@ var xxx_messageInfo_GitDirectoryGeneratorItem proto.InternalMessageInfo func (m *GitFileGeneratorItem) Reset() { *m = GitFileGeneratorItem{} } func (*GitFileGeneratorItem) ProtoMessage() {} func (*GitFileGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{63} + return fileDescriptor_030104ce3b95bcac, []int{64} } func (m *GitFileGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1836,7 +1864,7 @@ var xxx_messageInfo_GitFileGeneratorItem proto.InternalMessageInfo func (m *GitGenerator) Reset() { *m = GitGenerator{} } func (*GitGenerator) ProtoMessage() {} func (*GitGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{64} + return fileDescriptor_030104ce3b95bcac, []int{65} } func (m *GitGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1864,7 +1892,7 @@ var xxx_messageInfo_GitGenerator proto.InternalMessageInfo func (m *GnuPGPublicKey) Reset() { *m = GnuPGPublicKey{} } func (*GnuPGPublicKey) ProtoMessage() {} func (*GnuPGPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{65} + return fileDescriptor_030104ce3b95bcac, []int{66} } func (m *GnuPGPublicKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1892,7 +1920,7 @@ var xxx_messageInfo_GnuPGPublicKey proto.InternalMessageInfo func (m *GnuPGPublicKeyList) Reset() { *m = GnuPGPublicKeyList{} } func (*GnuPGPublicKeyList) ProtoMessage() {} func (*GnuPGPublicKeyList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{66} + return fileDescriptor_030104ce3b95bcac, []int{67} } func (m *GnuPGPublicKeyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1920,7 +1948,7 @@ var xxx_messageInfo_GnuPGPublicKeyList proto.InternalMessageInfo func (m *HealthStatus) Reset() { *m = HealthStatus{} } func (*HealthStatus) ProtoMessage() {} func (*HealthStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{67} + return fileDescriptor_030104ce3b95bcac, []int{68} } func (m *HealthStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1948,7 +1976,7 @@ var xxx_messageInfo_HealthStatus proto.InternalMessageInfo func (m *HelmFileParameter) Reset() { *m = HelmFileParameter{} } func (*HelmFileParameter) ProtoMessage() {} func (*HelmFileParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{68} + return fileDescriptor_030104ce3b95bcac, []int{69} } func (m *HelmFileParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1976,7 +2004,7 @@ var xxx_messageInfo_HelmFileParameter proto.InternalMessageInfo func (m *HelmOptions) Reset() { *m = HelmOptions{} } func (*HelmOptions) ProtoMessage() {} func (*HelmOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{69} + return fileDescriptor_030104ce3b95bcac, []int{70} } func (m *HelmOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2004,7 +2032,7 @@ var xxx_messageInfo_HelmOptions proto.InternalMessageInfo func (m *HelmParameter) Reset() { *m = HelmParameter{} } func (*HelmParameter) ProtoMessage() {} func (*HelmParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{70} + return fileDescriptor_030104ce3b95bcac, []int{71} } func (m *HelmParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2032,7 +2060,7 @@ var xxx_messageInfo_HelmParameter proto.InternalMessageInfo func (m *HostInfo) Reset() { *m = HostInfo{} } func (*HostInfo) ProtoMessage() {} func (*HostInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{71} + return fileDescriptor_030104ce3b95bcac, []int{72} } func (m *HostInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2060,7 +2088,7 @@ var xxx_messageInfo_HostInfo proto.InternalMessageInfo func (m *HostResourceInfo) Reset() { *m = HostResourceInfo{} } func (*HostResourceInfo) ProtoMessage() {} func (*HostResourceInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{72} + return fileDescriptor_030104ce3b95bcac, []int{73} } func (m *HostResourceInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2085,10 +2113,66 @@ func (m *HostResourceInfo) XXX_DiscardUnknown() { var xxx_messageInfo_HostResourceInfo proto.InternalMessageInfo +func (m *HydrateOperation) Reset() { *m = HydrateOperation{} } +func (*HydrateOperation) ProtoMessage() {} +func (*HydrateOperation) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{74} +} +func (m *HydrateOperation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HydrateOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *HydrateOperation) XXX_Merge(src proto.Message) { + xxx_messageInfo_HydrateOperation.Merge(m, src) +} +func (m *HydrateOperation) XXX_Size() int { + return m.Size() +} +func (m *HydrateOperation) XXX_DiscardUnknown() { + xxx_messageInfo_HydrateOperation.DiscardUnknown(m) +} + +var xxx_messageInfo_HydrateOperation proto.InternalMessageInfo + +func (m *HydrateTo) Reset() { *m = HydrateTo{} } +func (*HydrateTo) ProtoMessage() {} +func (*HydrateTo) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{75} +} +func (m *HydrateTo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HydrateTo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *HydrateTo) XXX_Merge(src proto.Message) { + xxx_messageInfo_HydrateTo.Merge(m, src) +} +func (m *HydrateTo) XXX_Size() int { + return m.Size() +} +func (m *HydrateTo) XXX_DiscardUnknown() { + xxx_messageInfo_HydrateTo.DiscardUnknown(m) +} + +var xxx_messageInfo_HydrateTo proto.InternalMessageInfo + func (m *Info) Reset() { *m = Info{} } func (*Info) ProtoMessage() {} func (*Info) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{73} + return fileDescriptor_030104ce3b95bcac, []int{76} } func (m *Info) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2116,7 +2200,7 @@ var xxx_messageInfo_Info proto.InternalMessageInfo func (m *InfoItem) Reset() { *m = InfoItem{} } func (*InfoItem) ProtoMessage() {} func (*InfoItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{74} + return fileDescriptor_030104ce3b95bcac, []int{77} } func (m *InfoItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2144,7 +2228,7 @@ var xxx_messageInfo_InfoItem proto.InternalMessageInfo func (m *JWTToken) Reset() { *m = JWTToken{} } func (*JWTToken) ProtoMessage() {} func (*JWTToken) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{75} + return fileDescriptor_030104ce3b95bcac, []int{78} } func (m *JWTToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2172,7 +2256,7 @@ var xxx_messageInfo_JWTToken proto.InternalMessageInfo func (m *JWTTokens) Reset() { *m = JWTTokens{} } func (*JWTTokens) ProtoMessage() {} func (*JWTTokens) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{76} + return fileDescriptor_030104ce3b95bcac, []int{79} } func (m *JWTTokens) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2200,7 +2284,7 @@ var xxx_messageInfo_JWTTokens proto.InternalMessageInfo func (m *JsonnetVar) Reset() { *m = JsonnetVar{} } func (*JsonnetVar) ProtoMessage() {} func (*JsonnetVar) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{77} + return fileDescriptor_030104ce3b95bcac, []int{80} } func (m *JsonnetVar) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2228,7 +2312,7 @@ var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo func (m *KnownTypeField) Reset() { *m = KnownTypeField{} } func (*KnownTypeField) ProtoMessage() {} func (*KnownTypeField) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{78} + return fileDescriptor_030104ce3b95bcac, []int{81} } func (m *KnownTypeField) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2256,7 +2340,7 @@ var xxx_messageInfo_KnownTypeField proto.InternalMessageInfo func (m *KustomizeGvk) Reset() { *m = KustomizeGvk{} } func (*KustomizeGvk) ProtoMessage() {} func (*KustomizeGvk) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{79} + return fileDescriptor_030104ce3b95bcac, []int{82} } func (m *KustomizeGvk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2284,7 +2368,7 @@ var xxx_messageInfo_KustomizeGvk proto.InternalMessageInfo func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} } func (*KustomizeOptions) ProtoMessage() {} func (*KustomizeOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{80} + return fileDescriptor_030104ce3b95bcac, []int{83} } func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2312,7 +2396,7 @@ var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo func (m *KustomizePatch) Reset() { *m = KustomizePatch{} } func (*KustomizePatch) ProtoMessage() {} func (*KustomizePatch) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{81} + return fileDescriptor_030104ce3b95bcac, []int{84} } func (m *KustomizePatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2340,7 +2424,7 @@ var xxx_messageInfo_KustomizePatch proto.InternalMessageInfo func (m *KustomizeReplica) Reset() { *m = KustomizeReplica{} } func (*KustomizeReplica) ProtoMessage() {} func (*KustomizeReplica) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{82} + return fileDescriptor_030104ce3b95bcac, []int{85} } func (m *KustomizeReplica) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2368,7 +2452,7 @@ var xxx_messageInfo_KustomizeReplica proto.InternalMessageInfo func (m *KustomizeResId) Reset() { *m = KustomizeResId{} } func (*KustomizeResId) ProtoMessage() {} func (*KustomizeResId) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{83} + return fileDescriptor_030104ce3b95bcac, []int{86} } func (m *KustomizeResId) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2396,7 +2480,7 @@ var xxx_messageInfo_KustomizeResId proto.InternalMessageInfo func (m *KustomizeSelector) Reset() { *m = KustomizeSelector{} } func (*KustomizeSelector) ProtoMessage() {} func (*KustomizeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{84} + return fileDescriptor_030104ce3b95bcac, []int{87} } func (m *KustomizeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2424,7 +2508,7 @@ var xxx_messageInfo_KustomizeSelector proto.InternalMessageInfo func (m *ListGenerator) Reset() { *m = ListGenerator{} } func (*ListGenerator) ProtoMessage() {} func (*ListGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{85} + return fileDescriptor_030104ce3b95bcac, []int{88} } func (m *ListGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2452,7 +2536,7 @@ var xxx_messageInfo_ListGenerator proto.InternalMessageInfo func (m *ManagedNamespaceMetadata) Reset() { *m = ManagedNamespaceMetadata{} } func (*ManagedNamespaceMetadata) ProtoMessage() {} func (*ManagedNamespaceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{86} + return fileDescriptor_030104ce3b95bcac, []int{89} } func (m *ManagedNamespaceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2480,7 +2564,7 @@ var xxx_messageInfo_ManagedNamespaceMetadata proto.InternalMessageInfo func (m *MatrixGenerator) Reset() { *m = MatrixGenerator{} } func (*MatrixGenerator) ProtoMessage() {} func (*MatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{87} + return fileDescriptor_030104ce3b95bcac, []int{90} } func (m *MatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2508,7 +2592,7 @@ var xxx_messageInfo_MatrixGenerator proto.InternalMessageInfo func (m *MergeGenerator) Reset() { *m = MergeGenerator{} } func (*MergeGenerator) ProtoMessage() {} func (*MergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{88} + return fileDescriptor_030104ce3b95bcac, []int{91} } func (m *MergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2536,7 +2620,7 @@ var xxx_messageInfo_MergeGenerator proto.InternalMessageInfo func (m *NestedMatrixGenerator) Reset() { *m = NestedMatrixGenerator{} } func (*NestedMatrixGenerator) ProtoMessage() {} func (*NestedMatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{89} + return fileDescriptor_030104ce3b95bcac, []int{92} } func (m *NestedMatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2564,7 +2648,7 @@ var xxx_messageInfo_NestedMatrixGenerator proto.InternalMessageInfo func (m *NestedMergeGenerator) Reset() { *m = NestedMergeGenerator{} } func (*NestedMergeGenerator) ProtoMessage() {} func (*NestedMergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{90} + return fileDescriptor_030104ce3b95bcac, []int{93} } func (m *NestedMergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2592,7 +2676,7 @@ var xxx_messageInfo_NestedMergeGenerator proto.InternalMessageInfo func (m *Operation) Reset() { *m = Operation{} } func (*Operation) ProtoMessage() {} func (*Operation) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{91} + return fileDescriptor_030104ce3b95bcac, []int{94} } func (m *Operation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2620,7 +2704,7 @@ var xxx_messageInfo_Operation proto.InternalMessageInfo func (m *OperationInitiator) Reset() { *m = OperationInitiator{} } func (*OperationInitiator) ProtoMessage() {} func (*OperationInitiator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{92} + return fileDescriptor_030104ce3b95bcac, []int{95} } func (m *OperationInitiator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2648,7 +2732,7 @@ var xxx_messageInfo_OperationInitiator proto.InternalMessageInfo func (m *OperationState) Reset() { *m = OperationState{} } func (*OperationState) ProtoMessage() {} func (*OperationState) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{93} + return fileDescriptor_030104ce3b95bcac, []int{96} } func (m *OperationState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2676,7 +2760,7 @@ var xxx_messageInfo_OperationState proto.InternalMessageInfo func (m *OptionalArray) Reset() { *m = OptionalArray{} } func (*OptionalArray) ProtoMessage() {} func (*OptionalArray) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{94} + return fileDescriptor_030104ce3b95bcac, []int{97} } func (m *OptionalArray) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2704,7 +2788,7 @@ var xxx_messageInfo_OptionalArray proto.InternalMessageInfo func (m *OptionalMap) Reset() { *m = OptionalMap{} } func (*OptionalMap) ProtoMessage() {} func (*OptionalMap) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{95} + return fileDescriptor_030104ce3b95bcac, []int{98} } func (m *OptionalMap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2732,7 +2816,7 @@ var xxx_messageInfo_OptionalMap proto.InternalMessageInfo func (m *OrphanedResourceKey) Reset() { *m = OrphanedResourceKey{} } func (*OrphanedResourceKey) ProtoMessage() {} func (*OrphanedResourceKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{96} + return fileDescriptor_030104ce3b95bcac, []int{99} } func (m *OrphanedResourceKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2760,7 +2844,7 @@ var xxx_messageInfo_OrphanedResourceKey proto.InternalMessageInfo func (m *OrphanedResourcesMonitorSettings) Reset() { *m = OrphanedResourcesMonitorSettings{} } func (*OrphanedResourcesMonitorSettings) ProtoMessage() {} func (*OrphanedResourcesMonitorSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{97} + return fileDescriptor_030104ce3b95bcac, []int{100} } func (m *OrphanedResourcesMonitorSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2788,7 +2872,7 @@ var xxx_messageInfo_OrphanedResourcesMonitorSettings proto.InternalMessageInfo func (m *OverrideIgnoreDiff) Reset() { *m = OverrideIgnoreDiff{} } func (*OverrideIgnoreDiff) ProtoMessage() {} func (*OverrideIgnoreDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{98} + return fileDescriptor_030104ce3b95bcac, []int{101} } func (m *OverrideIgnoreDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2816,7 +2900,7 @@ var xxx_messageInfo_OverrideIgnoreDiff proto.InternalMessageInfo func (m *PluginConfigMapRef) Reset() { *m = PluginConfigMapRef{} } func (*PluginConfigMapRef) ProtoMessage() {} func (*PluginConfigMapRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{99} + return fileDescriptor_030104ce3b95bcac, []int{102} } func (m *PluginConfigMapRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2844,7 +2928,7 @@ var xxx_messageInfo_PluginConfigMapRef proto.InternalMessageInfo func (m *PluginGenerator) Reset() { *m = PluginGenerator{} } func (*PluginGenerator) ProtoMessage() {} func (*PluginGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{100} + return fileDescriptor_030104ce3b95bcac, []int{103} } func (m *PluginGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2872,7 +2956,7 @@ var xxx_messageInfo_PluginGenerator proto.InternalMessageInfo func (m *PluginInput) Reset() { *m = PluginInput{} } func (*PluginInput) ProtoMessage() {} func (*PluginInput) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{101} + return fileDescriptor_030104ce3b95bcac, []int{104} } func (m *PluginInput) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2900,7 +2984,7 @@ var xxx_messageInfo_PluginInput proto.InternalMessageInfo func (m *ProjectRole) Reset() { *m = ProjectRole{} } func (*ProjectRole) ProtoMessage() {} func (*ProjectRole) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{102} + return fileDescriptor_030104ce3b95bcac, []int{105} } func (m *ProjectRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2928,7 +3012,7 @@ var xxx_messageInfo_ProjectRole proto.InternalMessageInfo func (m *PullRequestGenerator) Reset() { *m = PullRequestGenerator{} } func (*PullRequestGenerator) ProtoMessage() {} func (*PullRequestGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{103} + return fileDescriptor_030104ce3b95bcac, []int{106} } func (m *PullRequestGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2956,7 +3040,7 @@ var xxx_messageInfo_PullRequestGenerator proto.InternalMessageInfo func (m *PullRequestGeneratorAzureDevOps) Reset() { *m = PullRequestGeneratorAzureDevOps{} } func (*PullRequestGeneratorAzureDevOps) ProtoMessage() {} func (*PullRequestGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{104} + return fileDescriptor_030104ce3b95bcac, []int{107} } func (m *PullRequestGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2984,7 +3068,7 @@ var xxx_messageInfo_PullRequestGeneratorAzureDevOps proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucket) Reset() { *m = PullRequestGeneratorBitbucket{} } func (*PullRequestGeneratorBitbucket) ProtoMessage() {} func (*PullRequestGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{105} + return fileDescriptor_030104ce3b95bcac, []int{108} } func (m *PullRequestGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3012,7 +3096,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucket proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucketServer) Reset() { *m = PullRequestGeneratorBitbucketServer{} } func (*PullRequestGeneratorBitbucketServer) ProtoMessage() {} func (*PullRequestGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{106} + return fileDescriptor_030104ce3b95bcac, []int{109} } func (m *PullRequestGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3040,7 +3124,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucketServer proto.InternalMessageInf func (m *PullRequestGeneratorFilter) Reset() { *m = PullRequestGeneratorFilter{} } func (*PullRequestGeneratorFilter) ProtoMessage() {} func (*PullRequestGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{107} + return fileDescriptor_030104ce3b95bcac, []int{110} } func (m *PullRequestGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3068,7 +3152,7 @@ var xxx_messageInfo_PullRequestGeneratorFilter proto.InternalMessageInfo func (m *PullRequestGeneratorGitLab) Reset() { *m = PullRequestGeneratorGitLab{} } func (*PullRequestGeneratorGitLab) ProtoMessage() {} func (*PullRequestGeneratorGitLab) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{108} + return fileDescriptor_030104ce3b95bcac, []int{111} } func (m *PullRequestGeneratorGitLab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3096,7 +3180,7 @@ var xxx_messageInfo_PullRequestGeneratorGitLab proto.InternalMessageInfo func (m *PullRequestGeneratorGitea) Reset() { *m = PullRequestGeneratorGitea{} } func (*PullRequestGeneratorGitea) ProtoMessage() {} func (*PullRequestGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{109} + return fileDescriptor_030104ce3b95bcac, []int{112} } func (m *PullRequestGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3124,7 +3208,7 @@ var xxx_messageInfo_PullRequestGeneratorGitea proto.InternalMessageInfo func (m *PullRequestGeneratorGithub) Reset() { *m = PullRequestGeneratorGithub{} } func (*PullRequestGeneratorGithub) ProtoMessage() {} func (*PullRequestGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{110} + return fileDescriptor_030104ce3b95bcac, []int{113} } func (m *PullRequestGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3152,7 +3236,7 @@ var xxx_messageInfo_PullRequestGeneratorGithub proto.InternalMessageInfo func (m *RefTarget) Reset() { *m = RefTarget{} } func (*RefTarget) ProtoMessage() {} func (*RefTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{111} + return fileDescriptor_030104ce3b95bcac, []int{114} } func (m *RefTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3180,7 +3264,7 @@ var xxx_messageInfo_RefTarget proto.InternalMessageInfo func (m *RepoCreds) Reset() { *m = RepoCreds{} } func (*RepoCreds) ProtoMessage() {} func (*RepoCreds) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{112} + return fileDescriptor_030104ce3b95bcac, []int{115} } func (m *RepoCreds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3208,7 +3292,7 @@ var xxx_messageInfo_RepoCreds proto.InternalMessageInfo func (m *RepoCredsList) Reset() { *m = RepoCredsList{} } func (*RepoCredsList) ProtoMessage() {} func (*RepoCredsList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{113} + return fileDescriptor_030104ce3b95bcac, []int{116} } func (m *RepoCredsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3236,7 +3320,7 @@ var xxx_messageInfo_RepoCredsList proto.InternalMessageInfo func (m *Repository) Reset() { *m = Repository{} } func (*Repository) ProtoMessage() {} func (*Repository) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{114} + return fileDescriptor_030104ce3b95bcac, []int{117} } func (m *Repository) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3264,7 +3348,7 @@ var xxx_messageInfo_Repository proto.InternalMessageInfo func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} } func (*RepositoryCertificate) ProtoMessage() {} func (*RepositoryCertificate) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{115} + return fileDescriptor_030104ce3b95bcac, []int{118} } func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3292,7 +3376,7 @@ var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} } func (*RepositoryCertificateList) ProtoMessage() {} func (*RepositoryCertificateList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{116} + return fileDescriptor_030104ce3b95bcac, []int{119} } func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3320,7 +3404,7 @@ var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo func (m *RepositoryList) Reset() { *m = RepositoryList{} } func (*RepositoryList) ProtoMessage() {} func (*RepositoryList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{117} + return fileDescriptor_030104ce3b95bcac, []int{120} } func (m *RepositoryList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3348,7 +3432,7 @@ var xxx_messageInfo_RepositoryList proto.InternalMessageInfo func (m *ResourceAction) Reset() { *m = ResourceAction{} } func (*ResourceAction) ProtoMessage() {} func (*ResourceAction) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{118} + return fileDescriptor_030104ce3b95bcac, []int{121} } func (m *ResourceAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3376,7 +3460,7 @@ var xxx_messageInfo_ResourceAction proto.InternalMessageInfo func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} } func (*ResourceActionDefinition) ProtoMessage() {} func (*ResourceActionDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{119} + return fileDescriptor_030104ce3b95bcac, []int{122} } func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3404,7 +3488,7 @@ var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} } func (*ResourceActionParam) ProtoMessage() {} func (*ResourceActionParam) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{120} + return fileDescriptor_030104ce3b95bcac, []int{123} } func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3432,7 +3516,7 @@ var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo func (m *ResourceActions) Reset() { *m = ResourceActions{} } func (*ResourceActions) ProtoMessage() {} func (*ResourceActions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{121} + return fileDescriptor_030104ce3b95bcac, []int{124} } func (m *ResourceActions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3460,7 +3544,7 @@ var xxx_messageInfo_ResourceActions proto.InternalMessageInfo func (m *ResourceDiff) Reset() { *m = ResourceDiff{} } func (*ResourceDiff) ProtoMessage() {} func (*ResourceDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{122} + return fileDescriptor_030104ce3b95bcac, []int{125} } func (m *ResourceDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3488,7 +3572,7 @@ var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} } func (*ResourceIgnoreDifferences) ProtoMessage() {} func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{123} + return fileDescriptor_030104ce3b95bcac, []int{126} } func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3516,7 +3600,7 @@ var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} } func (*ResourceNetworkingInfo) ProtoMessage() {} func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{124} + return fileDescriptor_030104ce3b95bcac, []int{127} } func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3544,7 +3628,7 @@ var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo func (m *ResourceNode) Reset() { *m = ResourceNode{} } func (*ResourceNode) ProtoMessage() {} func (*ResourceNode) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{125} + return fileDescriptor_030104ce3b95bcac, []int{128} } func (m *ResourceNode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3572,7 +3656,7 @@ var xxx_messageInfo_ResourceNode proto.InternalMessageInfo func (m *ResourceOverride) Reset() { *m = ResourceOverride{} } func (*ResourceOverride) ProtoMessage() {} func (*ResourceOverride) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{126} + return fileDescriptor_030104ce3b95bcac, []int{129} } func (m *ResourceOverride) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3600,7 +3684,7 @@ var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo func (m *ResourceRef) Reset() { *m = ResourceRef{} } func (*ResourceRef) ProtoMessage() {} func (*ResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{127} + return fileDescriptor_030104ce3b95bcac, []int{130} } func (m *ResourceRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3628,7 +3712,7 @@ var xxx_messageInfo_ResourceRef proto.InternalMessageInfo func (m *ResourceResult) Reset() { *m = ResourceResult{} } func (*ResourceResult) ProtoMessage() {} func (*ResourceResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{128} + return fileDescriptor_030104ce3b95bcac, []int{131} } func (m *ResourceResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3656,7 +3740,7 @@ var xxx_messageInfo_ResourceResult proto.InternalMessageInfo func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } func (*ResourceStatus) ProtoMessage() {} func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{129} + return fileDescriptor_030104ce3b95bcac, []int{132} } func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3684,7 +3768,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{130} + return fileDescriptor_030104ce3b95bcac, []int{133} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3712,7 +3796,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *RevisionHistory) Reset() { *m = RevisionHistory{} } func (*RevisionHistory) ProtoMessage() {} func (*RevisionHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{131} + return fileDescriptor_030104ce3b95bcac, []int{134} } func (m *RevisionHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3740,7 +3824,7 @@ var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} } func (*RevisionMetadata) ProtoMessage() {} func (*RevisionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{132} + return fileDescriptor_030104ce3b95bcac, []int{135} } func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3768,7 +3852,7 @@ var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo func (m *SCMProviderGenerator) Reset() { *m = SCMProviderGenerator{} } func (*SCMProviderGenerator) ProtoMessage() {} func (*SCMProviderGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{133} + return fileDescriptor_030104ce3b95bcac, []int{136} } func (m *SCMProviderGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3796,7 +3880,7 @@ var xxx_messageInfo_SCMProviderGenerator proto.InternalMessageInfo func (m *SCMProviderGeneratorAWSCodeCommit) Reset() { *m = SCMProviderGeneratorAWSCodeCommit{} } func (*SCMProviderGeneratorAWSCodeCommit) ProtoMessage() {} func (*SCMProviderGeneratorAWSCodeCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{134} + return fileDescriptor_030104ce3b95bcac, []int{137} } func (m *SCMProviderGeneratorAWSCodeCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3824,7 +3908,7 @@ var xxx_messageInfo_SCMProviderGeneratorAWSCodeCommit proto.InternalMessageInfo func (m *SCMProviderGeneratorAzureDevOps) Reset() { *m = SCMProviderGeneratorAzureDevOps{} } func (*SCMProviderGeneratorAzureDevOps) ProtoMessage() {} func (*SCMProviderGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{135} + return fileDescriptor_030104ce3b95bcac, []int{138} } func (m *SCMProviderGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3852,7 +3936,7 @@ var xxx_messageInfo_SCMProviderGeneratorAzureDevOps proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucket) Reset() { *m = SCMProviderGeneratorBitbucket{} } func (*SCMProviderGeneratorBitbucket) ProtoMessage() {} func (*SCMProviderGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{136} + return fileDescriptor_030104ce3b95bcac, []int{139} } func (m *SCMProviderGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3880,7 +3964,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucket proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucketServer) Reset() { *m = SCMProviderGeneratorBitbucketServer{} } func (*SCMProviderGeneratorBitbucketServer) ProtoMessage() {} func (*SCMProviderGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{137} + return fileDescriptor_030104ce3b95bcac, []int{140} } func (m *SCMProviderGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3908,7 +3992,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucketServer proto.InternalMessageInf func (m *SCMProviderGeneratorFilter) Reset() { *m = SCMProviderGeneratorFilter{} } func (*SCMProviderGeneratorFilter) ProtoMessage() {} func (*SCMProviderGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{138} + return fileDescriptor_030104ce3b95bcac, []int{141} } func (m *SCMProviderGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3936,7 +4020,7 @@ var xxx_messageInfo_SCMProviderGeneratorFilter proto.InternalMessageInfo func (m *SCMProviderGeneratorGitea) Reset() { *m = SCMProviderGeneratorGitea{} } func (*SCMProviderGeneratorGitea) ProtoMessage() {} func (*SCMProviderGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{139} + return fileDescriptor_030104ce3b95bcac, []int{142} } func (m *SCMProviderGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3964,7 +4048,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitea proto.InternalMessageInfo func (m *SCMProviderGeneratorGithub) Reset() { *m = SCMProviderGeneratorGithub{} } func (*SCMProviderGeneratorGithub) ProtoMessage() {} func (*SCMProviderGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{140} + return fileDescriptor_030104ce3b95bcac, []int{143} } func (m *SCMProviderGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3992,7 +4076,7 @@ var xxx_messageInfo_SCMProviderGeneratorGithub proto.InternalMessageInfo func (m *SCMProviderGeneratorGitlab) Reset() { *m = SCMProviderGeneratorGitlab{} } func (*SCMProviderGeneratorGitlab) ProtoMessage() {} func (*SCMProviderGeneratorGitlab) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{141} + return fileDescriptor_030104ce3b95bcac, []int{144} } func (m *SCMProviderGeneratorGitlab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4020,7 +4104,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitlab proto.InternalMessageInfo func (m *SecretRef) Reset() { *m = SecretRef{} } func (*SecretRef) ProtoMessage() {} func (*SecretRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{142} + return fileDescriptor_030104ce3b95bcac, []int{145} } func (m *SecretRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4048,7 +4132,7 @@ var xxx_messageInfo_SecretRef proto.InternalMessageInfo func (m *SignatureKey) Reset() { *m = SignatureKey{} } func (*SignatureKey) ProtoMessage() {} func (*SignatureKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{143} + return fileDescriptor_030104ce3b95bcac, []int{146} } func (m *SignatureKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4073,10 +4157,94 @@ func (m *SignatureKey) XXX_DiscardUnknown() { var xxx_messageInfo_SignatureKey proto.InternalMessageInfo +func (m *SourceHydrator) Reset() { *m = SourceHydrator{} } +func (*SourceHydrator) ProtoMessage() {} +func (*SourceHydrator) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{147} +} +func (m *SourceHydrator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SourceHydrator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SourceHydrator) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceHydrator.Merge(m, src) +} +func (m *SourceHydrator) XXX_Size() int { + return m.Size() +} +func (m *SourceHydrator) XXX_DiscardUnknown() { + xxx_messageInfo_SourceHydrator.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceHydrator proto.InternalMessageInfo + +func (m *SourceHydratorStatus) Reset() { *m = SourceHydratorStatus{} } +func (*SourceHydratorStatus) ProtoMessage() {} +func (*SourceHydratorStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{148} +} +func (m *SourceHydratorStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SourceHydratorStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SourceHydratorStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceHydratorStatus.Merge(m, src) +} +func (m *SourceHydratorStatus) XXX_Size() int { + return m.Size() +} +func (m *SourceHydratorStatus) XXX_DiscardUnknown() { + xxx_messageInfo_SourceHydratorStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceHydratorStatus proto.InternalMessageInfo + +func (m *SuccessfulHydrateOperation) Reset() { *m = SuccessfulHydrateOperation{} } +func (*SuccessfulHydrateOperation) ProtoMessage() {} +func (*SuccessfulHydrateOperation) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{149} +} +func (m *SuccessfulHydrateOperation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SuccessfulHydrateOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SuccessfulHydrateOperation) XXX_Merge(src proto.Message) { + xxx_messageInfo_SuccessfulHydrateOperation.Merge(m, src) +} +func (m *SuccessfulHydrateOperation) XXX_Size() int { + return m.Size() +} +func (m *SuccessfulHydrateOperation) XXX_DiscardUnknown() { + xxx_messageInfo_SuccessfulHydrateOperation.DiscardUnknown(m) +} + +var xxx_messageInfo_SuccessfulHydrateOperation proto.InternalMessageInfo + func (m *SyncOperation) Reset() { *m = SyncOperation{} } func (*SyncOperation) ProtoMessage() {} func (*SyncOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{144} + return fileDescriptor_030104ce3b95bcac, []int{150} } func (m *SyncOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4104,7 +4272,7 @@ var xxx_messageInfo_SyncOperation proto.InternalMessageInfo func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} } func (*SyncOperationResource) ProtoMessage() {} func (*SyncOperationResource) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{145} + return fileDescriptor_030104ce3b95bcac, []int{151} } func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4132,7 +4300,7 @@ var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} } func (*SyncOperationResult) ProtoMessage() {} func (*SyncOperationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{146} + return fileDescriptor_030104ce3b95bcac, []int{152} } func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4160,7 +4328,7 @@ var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo func (m *SyncPolicy) Reset() { *m = SyncPolicy{} } func (*SyncPolicy) ProtoMessage() {} func (*SyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{147} + return fileDescriptor_030104ce3b95bcac, []int{153} } func (m *SyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4188,7 +4356,7 @@ var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} } func (*SyncPolicyAutomated) ProtoMessage() {} func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{148} + return fileDescriptor_030104ce3b95bcac, []int{154} } func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4213,10 +4381,38 @@ func (m *SyncPolicyAutomated) XXX_DiscardUnknown() { var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo +func (m *SyncSource) Reset() { *m = SyncSource{} } +func (*SyncSource) ProtoMessage() {} +func (*SyncSource) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{155} +} +func (m *SyncSource) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SyncSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *SyncSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_SyncSource.Merge(m, src) +} +func (m *SyncSource) XXX_Size() int { + return m.Size() +} +func (m *SyncSource) XXX_DiscardUnknown() { + xxx_messageInfo_SyncSource.DiscardUnknown(m) +} + +var xxx_messageInfo_SyncSource proto.InternalMessageInfo + func (m *SyncStatus) Reset() { *m = SyncStatus{} } func (*SyncStatus) ProtoMessage() {} func (*SyncStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{149} + return fileDescriptor_030104ce3b95bcac, []int{156} } func (m *SyncStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4244,7 +4440,7 @@ var xxx_messageInfo_SyncStatus proto.InternalMessageInfo func (m *SyncStrategy) Reset() { *m = SyncStrategy{} } func (*SyncStrategy) ProtoMessage() {} func (*SyncStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{150} + return fileDescriptor_030104ce3b95bcac, []int{157} } func (m *SyncStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4272,7 +4468,7 @@ var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} } func (*SyncStrategyApply) ProtoMessage() {} func (*SyncStrategyApply) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{151} + return fileDescriptor_030104ce3b95bcac, []int{158} } func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4300,7 +4496,7 @@ var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} } func (*SyncStrategyHook) ProtoMessage() {} func (*SyncStrategyHook) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{152} + return fileDescriptor_030104ce3b95bcac, []int{159} } func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4328,7 +4524,7 @@ var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo func (m *SyncWindow) Reset() { *m = SyncWindow{} } func (*SyncWindow) ProtoMessage() {} func (*SyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{153} + return fileDescriptor_030104ce3b95bcac, []int{160} } func (m *SyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4356,7 +4552,7 @@ var xxx_messageInfo_SyncWindow proto.InternalMessageInfo func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} } func (*TLSClientConfig) ProtoMessage() {} func (*TLSClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{154} + return fileDescriptor_030104ce3b95bcac, []int{161} } func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4384,7 +4580,7 @@ var xxx_messageInfo_TLSClientConfig proto.InternalMessageInfo func (m *TagFilter) Reset() { *m = TagFilter{} } func (*TagFilter) ProtoMessage() {} func (*TagFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{155} + return fileDescriptor_030104ce3b95bcac, []int{162} } func (m *TagFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4476,6 +4672,7 @@ func init() { proto.RegisterType((*ConfigManagementPlugin)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigManagementPlugin") proto.RegisterType((*ConfigMapKeyRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConfigMapKeyRef") proto.RegisterType((*ConnectionState)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ConnectionState") + proto.RegisterType((*DrySource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DrySource") proto.RegisterType((*DuckTypeGenerator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DuckTypeGenerator") proto.RegisterMapType((map[string]string)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.DuckTypeGenerator.ValuesEntry") proto.RegisterType((*EnvEntry)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.EnvEntry") @@ -4494,6 +4691,8 @@ func init() { proto.RegisterType((*HelmParameter)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmParameter") proto.RegisterType((*HostInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HostInfo") proto.RegisterType((*HostResourceInfo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HostResourceInfo") + proto.RegisterType((*HydrateOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HydrateOperation") + proto.RegisterType((*HydrateTo)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HydrateTo") proto.RegisterType((*Info)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Info") proto.RegisterType((*InfoItem)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.InfoItem") proto.RegisterType((*JWTToken)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.JWTToken") @@ -4574,11 +4773,15 @@ func init() { proto.RegisterType((*SCMProviderGeneratorGitlab)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SCMProviderGeneratorGitlab") proto.RegisterType((*SecretRef)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SecretRef") proto.RegisterType((*SignatureKey)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SignatureKey") + proto.RegisterType((*SourceHydrator)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SourceHydrator") + proto.RegisterType((*SourceHydratorStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SourceHydratorStatus") + proto.RegisterType((*SuccessfulHydrateOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SuccessfulHydrateOperation") proto.RegisterType((*SyncOperation)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperation") proto.RegisterType((*SyncOperationResource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperationResource") proto.RegisterType((*SyncOperationResult)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncOperationResult") proto.RegisterType((*SyncPolicy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncPolicy") proto.RegisterType((*SyncPolicyAutomated)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncPolicyAutomated") + proto.RegisterType((*SyncSource)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncSource") proto.RegisterType((*SyncStatus)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStatus") proto.RegisterType((*SyncStrategy)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategy") proto.RegisterType((*SyncStrategyApply)(nil), "github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.SyncStrategyApply") @@ -4593,717 +4796,749 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 11357 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x1c, 0xc9, - 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0x11, 0x4d, 0xf2, 0x0e, 0xa4, 0xee, 0x0e, 0xf4, - 0x9c, 0x7d, 0x3a, 0x45, 0x77, 0x80, 0x8f, 0xba, 0x93, 0x2f, 0x3a, 0x4b, 0x32, 0x3e, 0x48, 0x10, - 0x24, 0x40, 0xe0, 0x1a, 0x20, 0x29, 0x9d, 0x7c, 0x3a, 0x0d, 0x66, 0x1b, 0x8b, 0x21, 0x66, 0x67, - 0xf6, 0x66, 0x66, 0x41, 0xe2, 0x2c, 0xc9, 0x92, 0x25, 0xd9, 0x72, 0xf4, 0x71, 0x8a, 0x94, 0xaa, - 0x9c, 0x13, 0x4b, 0x91, 0x2d, 0x27, 0x95, 0x54, 0x4a, 0x15, 0x25, 0xf9, 0x11, 0x27, 0xb6, 0xcb, - 0x15, 0x3b, 0xe5, 0x52, 0xe2, 0xa4, 0xec, 0x52, 0xa9, 0x2c, 0x25, 0xb1, 0x11, 0x89, 0x71, 0x2a, - 0xa9, 0xfc, 0x70, 0x55, 0x9c, 0xfc, 0x48, 0x31, 0xf9, 0x91, 0xea, 0xef, 0x9e, 0xd9, 0x59, 0x60, - 0x41, 0x0c, 0x40, 0x4a, 0xb9, 0x7f, 0xbb, 0xfd, 0x5e, 0xf7, 0xeb, 0xe9, 0x8f, 0xf7, 0x5e, 0xbf, - 0x7e, 0xef, 0x35, 0x2c, 0x36, 0xbc, 0x64, 0xb3, 0xbd, 0x3e, 0xe9, 0x86, 0xcd, 0x29, 0x27, 0x6a, - 0x84, 0xad, 0x28, 0xbc, 0xc9, 0x7e, 0x3c, 0xed, 0xd6, 0xa7, 0xb6, 0xcf, 0x4f, 0xb5, 0xb6, 0x1a, - 0x53, 0x4e, 0xcb, 0x8b, 0xa7, 0x9c, 0x56, 0xcb, 0xf7, 0x5c, 0x27, 0xf1, 0xc2, 0x60, 0x6a, 0xfb, - 0x19, 0xc7, 0x6f, 0x6d, 0x3a, 0xcf, 0x4c, 0x35, 0x48, 0x40, 0x22, 0x27, 0x21, 0xf5, 0xc9, 0x56, - 0x14, 0x26, 0x21, 0xfa, 0x69, 0xdd, 0xda, 0xa4, 0x6c, 0x8d, 0xfd, 0x78, 0xc5, 0xad, 0x4f, 0x6e, - 0x9f, 0x9f, 0x6c, 0x6d, 0x35, 0x26, 0x69, 0x6b, 0x93, 0x46, 0x6b, 0x93, 0xb2, 0xb5, 0xb3, 0x4f, - 0x1b, 0x7d, 0x69, 0x84, 0x8d, 0x70, 0x8a, 0x35, 0xba, 0xde, 0xde, 0x60, 0xff, 0xd8, 0x1f, 0xf6, - 0x8b, 0x13, 0x3b, 0x6b, 0x6f, 0x3d, 0x1f, 0x4f, 0x7a, 0x21, 0xed, 0xde, 0x94, 0x1b, 0x46, 0x64, - 0x6a, 0xbb, 0xa3, 0x43, 0x67, 0x2f, 0x69, 0x1c, 0x72, 0x3b, 0x21, 0x41, 0xec, 0x85, 0x41, 0xfc, - 0x34, 0xed, 0x02, 0x89, 0xb6, 0x49, 0x64, 0x7e, 0x9e, 0x81, 0x90, 0xd7, 0xd2, 0xb3, 0xba, 0xa5, - 0xa6, 0xe3, 0x6e, 0x7a, 0x01, 0x89, 0x76, 0x74, 0xf5, 0x26, 0x49, 0x9c, 0xbc, 0x5a, 0x53, 0xdd, - 0x6a, 0x45, 0xed, 0x20, 0xf1, 0x9a, 0xa4, 0xa3, 0xc2, 0xbb, 0xf6, 0xab, 0x10, 0xbb, 0x9b, 0xa4, - 0xe9, 0x74, 0xd4, 0x7b, 0x67, 0xb7, 0x7a, 0xed, 0xc4, 0xf3, 0xa7, 0xbc, 0x20, 0x89, 0x93, 0x28, - 0x5b, 0xc9, 0xfe, 0x55, 0x0b, 0x86, 0xa7, 0x6f, 0xac, 0x4e, 0xb7, 0x93, 0xcd, 0xd9, 0x30, 0xd8, - 0xf0, 0x1a, 0xe8, 0x39, 0x18, 0x74, 0xfd, 0x76, 0x9c, 0x90, 0xe8, 0xaa, 0xd3, 0x24, 0xe3, 0xd6, - 0x39, 0xeb, 0xc9, 0xda, 0xcc, 0xc9, 0x6f, 0xed, 0x4e, 0xbc, 0xe5, 0xce, 0xee, 0xc4, 0xe0, 0xac, - 0x06, 0x61, 0x13, 0x0f, 0xbd, 0x1d, 0x06, 0xa2, 0xd0, 0x27, 0xd3, 0xf8, 0xea, 0x78, 0x89, 0x55, - 0x19, 0x15, 0x55, 0x06, 0x30, 0x2f, 0xc6, 0x12, 0x4e, 0x51, 0x5b, 0x51, 0xb8, 0xe1, 0xf9, 0x64, - 0xbc, 0x9c, 0x46, 0x5d, 0xe1, 0xc5, 0x58, 0xc2, 0xed, 0x3f, 0x29, 0x01, 0x4c, 0xb7, 0x5a, 0x2b, - 0x51, 0x78, 0x93, 0xb8, 0x09, 0xfa, 0x30, 0x54, 0xe9, 0x30, 0xd7, 0x9d, 0xc4, 0x61, 0x1d, 0x1b, - 0x3c, 0xff, 0x93, 0x93, 0xfc, 0xab, 0x27, 0xcd, 0xaf, 0xd6, 0x8b, 0x8c, 0x62, 0x4f, 0x6e, 0x3f, - 0x33, 0xb9, 0xbc, 0x4e, 0xeb, 0x2f, 0x91, 0xc4, 0x99, 0x41, 0x82, 0x18, 0xe8, 0x32, 0xac, 0x5a, - 0x45, 0x01, 0xf4, 0xc5, 0x2d, 0xe2, 0xb2, 0x6f, 0x18, 0x3c, 0xbf, 0x38, 0x79, 0x98, 0xd5, 0x3c, - 0xa9, 0x7b, 0xbe, 0xda, 0x22, 0xee, 0xcc, 0x90, 0xa0, 0xdc, 0x47, 0xff, 0x61, 0x46, 0x07, 0x6d, - 0x43, 0x7f, 0x9c, 0x38, 0x49, 0x3b, 0x66, 0x43, 0x31, 0x78, 0xfe, 0x6a, 0x61, 0x14, 0x59, 0xab, - 0x33, 0x23, 0x82, 0x66, 0x3f, 0xff, 0x8f, 0x05, 0x35, 0xfb, 0xcf, 0x2c, 0x18, 0xd1, 0xc8, 0x8b, - 0x5e, 0x9c, 0xa0, 0x9f, 0xed, 0x18, 0xdc, 0xc9, 0xde, 0x06, 0x97, 0xd6, 0x66, 0x43, 0x7b, 0x42, - 0x10, 0xab, 0xca, 0x12, 0x63, 0x60, 0x9b, 0x50, 0xf1, 0x12, 0xd2, 0x8c, 0xc7, 0x4b, 0xe7, 0xca, - 0x4f, 0x0e, 0x9e, 0xbf, 0x54, 0xd4, 0x77, 0xce, 0x0c, 0x0b, 0xa2, 0x95, 0x05, 0xda, 0x3c, 0xe6, - 0x54, 0xec, 0xbf, 0x1c, 0x36, 0xbf, 0x8f, 0x0e, 0x38, 0x7a, 0x06, 0x06, 0xe3, 0xb0, 0x1d, 0xb9, - 0x04, 0x93, 0x56, 0x18, 0x8f, 0x5b, 0xe7, 0xca, 0x74, 0xe9, 0xd1, 0x45, 0xbd, 0xaa, 0x8b, 0xb1, - 0x89, 0x83, 0xbe, 0x60, 0xc1, 0x50, 0x9d, 0xc4, 0x89, 0x17, 0x30, 0xfa, 0xb2, 0xf3, 0x6b, 0x87, - 0xee, 0xbc, 0x2c, 0x9c, 0xd3, 0x8d, 0xcf, 0x9c, 0x12, 0x1f, 0x32, 0x64, 0x14, 0xc6, 0x38, 0x45, - 0x9f, 0x6e, 0xce, 0x3a, 0x89, 0xdd, 0xc8, 0x6b, 0xd1, 0xff, 0x62, 0xfb, 0xa8, 0xcd, 0x39, 0xa7, - 0x41, 0xd8, 0xc4, 0x43, 0x01, 0x54, 0xe8, 0xe6, 0x8b, 0xc7, 0xfb, 0x58, 0xff, 0x17, 0x0e, 0xd7, - 0x7f, 0x31, 0xa8, 0x74, 0x5f, 0xeb, 0xd1, 0xa7, 0xff, 0x62, 0xcc, 0xc9, 0xa0, 0xcf, 0x5b, 0x30, - 0x2e, 0x98, 0x03, 0x26, 0x7c, 0x40, 0x6f, 0x6c, 0x7a, 0x09, 0xf1, 0xbd, 0x38, 0x19, 0xaf, 0xb0, - 0x3e, 0x4c, 0xf5, 0xb6, 0xb6, 0xe6, 0xa3, 0xb0, 0xdd, 0xba, 0xe2, 0x05, 0xf5, 0x99, 0x73, 0x82, - 0xd2, 0xf8, 0x6c, 0x97, 0x86, 0x71, 0x57, 0x92, 0xe8, 0xcb, 0x16, 0x9c, 0x0d, 0x9c, 0x26, 0x89, - 0x5b, 0x0e, 0x9d, 0x5a, 0x0e, 0x9e, 0xf1, 0x1d, 0x77, 0x8b, 0xf5, 0xa8, 0xff, 0xde, 0x7a, 0x64, - 0x8b, 0x1e, 0x9d, 0xbd, 0xda, 0xb5, 0x69, 0xbc, 0x07, 0x59, 0xf4, 0x75, 0x0b, 0xc6, 0xc2, 0xa8, - 0xb5, 0xe9, 0x04, 0xa4, 0x2e, 0xa1, 0xf1, 0xf8, 0x00, 0xdb, 0x7a, 0x1f, 0x3a, 0xdc, 0x14, 0x2d, - 0x67, 0x9b, 0x5d, 0x0a, 0x03, 0x2f, 0x09, 0xa3, 0x55, 0x92, 0x24, 0x5e, 0xd0, 0x88, 0x67, 0x4e, - 0xdf, 0xd9, 0x9d, 0x18, 0xeb, 0xc0, 0xc2, 0x9d, 0xfd, 0x41, 0x3f, 0x07, 0x83, 0xf1, 0x4e, 0xe0, - 0xde, 0xf0, 0x82, 0x7a, 0x78, 0x2b, 0x1e, 0xaf, 0x16, 0xb1, 0x7d, 0x57, 0x55, 0x83, 0x62, 0x03, - 0x6a, 0x02, 0xd8, 0xa4, 0x96, 0x3f, 0x71, 0x7a, 0x29, 0xd5, 0x8a, 0x9e, 0x38, 0xbd, 0x98, 0xf6, - 0x20, 0x8b, 0x7e, 0xc9, 0x82, 0xe1, 0xd8, 0x6b, 0x04, 0x4e, 0xd2, 0x8e, 0xc8, 0x15, 0xb2, 0x13, - 0x8f, 0x03, 0xeb, 0xc8, 0xe5, 0x43, 0x8e, 0x8a, 0xd1, 0xe4, 0xcc, 0x69, 0xd1, 0xc7, 0x61, 0xb3, - 0x34, 0xc6, 0x69, 0xba, 0x79, 0x1b, 0x4d, 0x2f, 0xeb, 0xc1, 0x62, 0x37, 0x9a, 0x5e, 0xd4, 0x5d, - 0x49, 0xa2, 0x9f, 0x81, 0x13, 0xbc, 0x48, 0x8d, 0x6c, 0x3c, 0x3e, 0xc4, 0x18, 0xed, 0xa9, 0x3b, - 0xbb, 0x13, 0x27, 0x56, 0x33, 0x30, 0xdc, 0x81, 0x8d, 0x5e, 0x85, 0x89, 0x16, 0x89, 0x9a, 0x5e, - 0xb2, 0x1c, 0xf8, 0x3b, 0x92, 0x7d, 0xbb, 0x61, 0x8b, 0xd4, 0x45, 0x77, 0xe2, 0xf1, 0xe1, 0x73, - 0xd6, 0x93, 0xd5, 0x99, 0xb7, 0x89, 0x6e, 0x4e, 0xac, 0xec, 0x8d, 0x8e, 0xf7, 0x6b, 0x0f, 0xfd, - 0x81, 0x05, 0x67, 0x0d, 0x2e, 0xbb, 0x4a, 0xa2, 0x6d, 0xcf, 0x25, 0xd3, 0xae, 0x1b, 0xb6, 0x83, - 0x24, 0x1e, 0x1f, 0x61, 0xc3, 0xb8, 0x7e, 0x14, 0x3c, 0x3f, 0x4d, 0x4a, 0xaf, 0xcb, 0xae, 0x28, - 0x31, 0xde, 0xa3, 0xa7, 0xf6, 0xbf, 0x2e, 0xc1, 0x89, 0xac, 0x06, 0x80, 0xfe, 0x9e, 0x05, 0xa3, - 0x37, 0x6f, 0x25, 0x6b, 0xe1, 0x16, 0x09, 0xe2, 0x99, 0x1d, 0xca, 0xa7, 0x99, 0xec, 0x1b, 0x3c, - 0xef, 0x16, 0xab, 0x6b, 0x4c, 0x5e, 0x4e, 0x53, 0xb9, 0x10, 0x24, 0xd1, 0xce, 0xcc, 0xc3, 0xe2, - 0x9b, 0x46, 0x2f, 0xdf, 0x58, 0x33, 0xa1, 0x38, 0xdb, 0xa9, 0xb3, 0x9f, 0xb5, 0xe0, 0x54, 0x5e, - 0x13, 0xe8, 0x04, 0x94, 0xb7, 0xc8, 0x0e, 0xd7, 0x44, 0x31, 0xfd, 0x89, 0x5e, 0x86, 0xca, 0xb6, - 0xe3, 0xb7, 0x89, 0x50, 0xd3, 0xe6, 0x0f, 0xf7, 0x21, 0xaa, 0x67, 0x98, 0xb7, 0xfa, 0xee, 0xd2, - 0xf3, 0x96, 0xfd, 0x47, 0x65, 0x18, 0x34, 0x26, 0xed, 0x18, 0x54, 0xcf, 0x30, 0xa5, 0x7a, 0x2e, - 0x15, 0xb6, 0xde, 0xba, 0xea, 0x9e, 0xb7, 0x32, 0xba, 0xe7, 0x72, 0x71, 0x24, 0xf7, 0x54, 0x3e, - 0x51, 0x02, 0xb5, 0xb0, 0x45, 0x8f, 0x21, 0x54, 0x87, 0xe9, 0x2b, 0x62, 0x0a, 0x97, 0x65, 0x73, - 0x33, 0xc3, 0x77, 0x76, 0x27, 0x6a, 0xea, 0x2f, 0xd6, 0x84, 0xec, 0xef, 0x5a, 0x70, 0xca, 0xe8, - 0xe3, 0x6c, 0x18, 0xd4, 0x3d, 0x36, 0xb5, 0xe7, 0xa0, 0x2f, 0xd9, 0x69, 0xc9, 0xa3, 0x8e, 0x1a, - 0xa9, 0xb5, 0x9d, 0x16, 0xc1, 0x0c, 0x42, 0x4f, 0x2c, 0x4d, 0x12, 0xc7, 0x4e, 0x83, 0x64, 0x0f, - 0x37, 0x4b, 0xbc, 0x18, 0x4b, 0x38, 0x8a, 0x00, 0xf9, 0x4e, 0x9c, 0xac, 0x45, 0x4e, 0x10, 0xb3, - 0xe6, 0xd7, 0xbc, 0x26, 0x11, 0x03, 0xfc, 0x57, 0x7a, 0x5b, 0x31, 0xb4, 0xc6, 0xcc, 0x43, 0x77, - 0x76, 0x27, 0xd0, 0x62, 0x47, 0x4b, 0x38, 0xa7, 0x75, 0xfb, 0xcb, 0x16, 0x3c, 0x94, 0xcf, 0x60, - 0xd0, 0x13, 0xd0, 0xcf, 0xcf, 0xb9, 0xe2, 0xeb, 0xf4, 0x94, 0xb0, 0x52, 0x2c, 0xa0, 0x68, 0x0a, - 0x6a, 0x4a, 0xe0, 0x89, 0x6f, 0x1c, 0x13, 0xa8, 0x35, 0x2d, 0x25, 0x35, 0x0e, 0x1d, 0x34, 0xfa, - 0x47, 0xa8, 0xa0, 0x6a, 0xd0, 0xd8, 0xc1, 0x90, 0x41, 0xec, 0xef, 0x58, 0xf0, 0xe3, 0xbd, 0xb0, - 0xbd, 0xa3, 0xeb, 0xe3, 0x2a, 0x9c, 0xae, 0x93, 0x0d, 0xa7, 0xed, 0x27, 0x69, 0x8a, 0xa2, 0xd3, - 0x8f, 0x8a, 0xca, 0xa7, 0xe7, 0xf2, 0x90, 0x70, 0x7e, 0x5d, 0xfb, 0x3f, 0x59, 0x30, 0x6a, 0x7c, - 0xd6, 0x31, 0x1c, 0x9d, 0x82, 0xf4, 0xd1, 0x69, 0xa1, 0xb0, 0x6d, 0xda, 0xe5, 0xec, 0xf4, 0x79, - 0x0b, 0xce, 0x1a, 0x58, 0x4b, 0x4e, 0xe2, 0x6e, 0x5e, 0xb8, 0xdd, 0x8a, 0x48, 0x1c, 0xd3, 0x25, - 0xf5, 0xa8, 0xc1, 0x8e, 0x67, 0x06, 0x45, 0x0b, 0xe5, 0x2b, 0x64, 0x87, 0xf3, 0xe6, 0xa7, 0xa0, - 0xca, 0xf7, 0x5c, 0x18, 0x89, 0x49, 0x52, 0xdf, 0xb6, 0x2c, 0xca, 0xb1, 0xc2, 0x40, 0x36, 0xf4, - 0x33, 0x9e, 0x4b, 0x79, 0x10, 0x55, 0x13, 0x80, 0xce, 0xfb, 0x75, 0x56, 0x82, 0x05, 0xc4, 0x8e, - 0x53, 0xdd, 0x59, 0x89, 0x08, 0x5b, 0x0f, 0xf5, 0x8b, 0x1e, 0xf1, 0xeb, 0x31, 0x3d, 0xd6, 0x39, - 0x41, 0x10, 0x26, 0xe2, 0x84, 0x66, 0x1c, 0xeb, 0xa6, 0x75, 0x31, 0x36, 0x71, 0x28, 0x51, 0xdf, - 0x59, 0x27, 0x3e, 0x1f, 0x51, 0x41, 0x74, 0x91, 0x95, 0x60, 0x01, 0xb1, 0xef, 0x94, 0xd8, 0x01, - 0x52, 0x71, 0x34, 0x72, 0x1c, 0xd6, 0x87, 0x28, 0x25, 0x02, 0x56, 0x8a, 0xe3, 0xc7, 0xa4, 0xbb, - 0x05, 0xe2, 0xb5, 0x8c, 0x14, 0xc0, 0x85, 0x52, 0xdd, 0xdb, 0x0a, 0xf1, 0xf1, 0x32, 0x4c, 0xa4, - 0x2b, 0x74, 0x08, 0x11, 0x7a, 0xe4, 0x35, 0x08, 0x65, 0xed, 0x51, 0x06, 0x3e, 0x36, 0xf1, 0xba, - 0xf0, 0xe1, 0xd2, 0x51, 0xf2, 0x61, 0x53, 0x4c, 0x94, 0xf7, 0x11, 0x13, 0x4f, 0xa8, 0x51, 0xef, - 0xcb, 0xf0, 0xbc, 0xb4, 0xa8, 0x3c, 0x07, 0x7d, 0x71, 0x42, 0x5a, 0xe3, 0x95, 0x34, 0x9b, 0x5d, - 0x4d, 0x48, 0x0b, 0x33, 0x08, 0x7a, 0x0f, 0x8c, 0x26, 0x4e, 0xd4, 0x20, 0x49, 0x44, 0xb6, 0x3d, - 0x66, 0xbb, 0x64, 0xe7, 0xd9, 0xda, 0xcc, 0x49, 0xaa, 0x75, 0xad, 0x31, 0x10, 0x96, 0x20, 0x9c, - 0xc5, 0xb5, 0xff, 0x7b, 0x09, 0x1e, 0x4e, 0x4f, 0x81, 0x16, 0x8c, 0xef, 0x4b, 0x09, 0xc6, 0x77, - 0x98, 0x82, 0xf1, 0xee, 0xee, 0xc4, 0x5b, 0xbb, 0x54, 0xfb, 0xa1, 0x91, 0x9b, 0x68, 0x3e, 0x33, - 0x09, 0x53, 0xe9, 0x49, 0xb8, 0xbb, 0x3b, 0xf1, 0x68, 0x97, 0x6f, 0xcc, 0xcc, 0xd2, 0x13, 0xd0, - 0x1f, 0x11, 0x27, 0x0e, 0x03, 0x31, 0x4f, 0x6a, 0x36, 0x31, 0x2b, 0xc5, 0x02, 0x6a, 0x7f, 0xbb, - 0x96, 0x1d, 0xec, 0x79, 0x6e, 0x8f, 0x0d, 0x23, 0xe4, 0x41, 0x1f, 0x3b, 0xb5, 0x71, 0xce, 0x72, - 0xe5, 0x70, 0xbb, 0x90, 0x4a, 0x11, 0xd5, 0xf4, 0x4c, 0x95, 0xce, 0x1a, 0x2d, 0xc2, 0x8c, 0x04, - 0xba, 0x0d, 0x55, 0x57, 0x1e, 0xa6, 0x4a, 0x45, 0x98, 0x1d, 0xc5, 0x51, 0x4a, 0x53, 0x1c, 0xa2, - 0xec, 0x5e, 0x9d, 0xc0, 0x14, 0x35, 0x44, 0xa0, 0xdc, 0xf0, 0x12, 0x31, 0xad, 0x87, 0x3c, 0x2e, - 0xcf, 0x7b, 0xc6, 0x27, 0x0e, 0x50, 0x19, 0x34, 0xef, 0x25, 0x98, 0xb6, 0x8f, 0x3e, 0x6d, 0xc1, - 0x60, 0xec, 0x36, 0x57, 0xa2, 0x70, 0xdb, 0xab, 0x93, 0x48, 0xe8, 0x98, 0x87, 0xe4, 0x6c, 0xab, - 0xb3, 0x4b, 0xb2, 0x41, 0x4d, 0x97, 0x9b, 0x2f, 0x34, 0x04, 0x9b, 0x74, 0xe9, 0xd9, 0xeb, 0x61, - 0xf1, 0xed, 0x73, 0xc4, 0x65, 0x3b, 0x4e, 0x9e, 0x99, 0xd9, 0x4a, 0x39, 0xb4, 0xce, 0x3d, 0xd7, - 0x76, 0xb7, 0xe8, 0x7e, 0xd3, 0x1d, 0x7a, 0xeb, 0x9d, 0xdd, 0x89, 0x87, 0x67, 0xf3, 0x69, 0xe2, - 0x6e, 0x9d, 0x61, 0x03, 0xd6, 0x6a, 0xfb, 0x3e, 0x26, 0xaf, 0xb6, 0x09, 0xb3, 0x88, 0x15, 0x30, - 0x60, 0x2b, 0xba, 0xc1, 0xcc, 0x80, 0x19, 0x10, 0x6c, 0xd2, 0x45, 0xaf, 0x42, 0x7f, 0xd3, 0x49, - 0x22, 0xef, 0xb6, 0x30, 0x83, 0x1d, 0xf2, 0x14, 0xb4, 0xc4, 0xda, 0xd2, 0xc4, 0x99, 0xa0, 0xe7, - 0x85, 0x58, 0x10, 0x42, 0x4d, 0xa8, 0x34, 0x49, 0xd4, 0x20, 0xe3, 0xd5, 0x22, 0x4c, 0xfe, 0x4b, - 0xb4, 0x29, 0x4d, 0xb0, 0x46, 0x95, 0x2b, 0x56, 0x86, 0x39, 0x15, 0xf4, 0x32, 0x54, 0x63, 0xe2, - 0x13, 0x97, 0xaa, 0x47, 0x35, 0x46, 0xf1, 0x9d, 0x3d, 0xaa, 0x8a, 0x54, 0x2f, 0x59, 0x15, 0x55, - 0xf9, 0x06, 0x93, 0xff, 0xb0, 0x6a, 0x92, 0x0e, 0x60, 0xcb, 0x6f, 0x37, 0xbc, 0x60, 0x1c, 0x8a, - 0x18, 0xc0, 0x15, 0xd6, 0x56, 0x66, 0x00, 0x79, 0x21, 0x16, 0x84, 0xec, 0xff, 0x62, 0x01, 0x4a, - 0x33, 0xb5, 0x63, 0xd0, 0x89, 0x5f, 0x4d, 0xeb, 0xc4, 0x8b, 0x45, 0x2a, 0x2d, 0x5d, 0xd4, 0xe2, - 0xdf, 0xaa, 0x41, 0x46, 0x1c, 0x5c, 0x25, 0x71, 0x42, 0xea, 0x6f, 0xb2, 0xf0, 0x37, 0x59, 0xf8, - 0x9b, 0x2c, 0x5c, 0xb1, 0xf0, 0xf5, 0x0c, 0x0b, 0x7f, 0xaf, 0xb1, 0xeb, 0xf5, 0xfd, 0xfa, 0x2b, - 0xea, 0x02, 0xde, 0xec, 0x81, 0x81, 0x40, 0x39, 0xc1, 0xe5, 0xd5, 0xe5, 0xab, 0xb9, 0x3c, 0xfb, - 0x95, 0x34, 0xcf, 0x3e, 0x2c, 0x89, 0xff, 0x1f, 0xb8, 0xf4, 0x1f, 0x58, 0xf0, 0xb6, 0x34, 0xf7, - 0x92, 0x2b, 0x67, 0xa1, 0x11, 0x84, 0x11, 0x99, 0xf3, 0x36, 0x36, 0x48, 0x44, 0x02, 0x97, 0xc4, - 0xca, 0xb6, 0x63, 0x75, 0xb3, 0xed, 0xa0, 0x67, 0x61, 0xe8, 0x66, 0x1c, 0x06, 0x2b, 0xa1, 0x17, - 0x08, 0x16, 0x44, 0x4f, 0x1c, 0x27, 0xee, 0xec, 0x4e, 0x0c, 0xd1, 0x11, 0x95, 0xe5, 0x38, 0x85, - 0x85, 0x66, 0x61, 0xec, 0xe6, 0xab, 0x2b, 0x4e, 0x62, 0x58, 0x13, 0xe4, 0xb9, 0x9f, 0xdd, 0x47, - 0x5d, 0x7e, 0x31, 0x03, 0xc4, 0x9d, 0xf8, 0xf6, 0xdf, 0x2e, 0xc1, 0x99, 0xcc, 0x87, 0x84, 0xbe, - 0x1f, 0xb6, 0x13, 0x7a, 0x26, 0x42, 0x5f, 0xb5, 0xe0, 0x44, 0x33, 0x6d, 0xb0, 0x88, 0x85, 0xb9, - 0xfb, 0xfd, 0x85, 0xc9, 0x88, 0x8c, 0x45, 0x64, 0x66, 0x5c, 0x8c, 0xd0, 0x89, 0x0c, 0x20, 0xc6, - 0x1d, 0x7d, 0x41, 0x2f, 0x43, 0xad, 0xe9, 0xdc, 0xbe, 0xd6, 0xaa, 0x3b, 0x89, 0x3c, 0x8e, 0x76, - 0xb7, 0x22, 0xb4, 0x13, 0xcf, 0x9f, 0xe4, 0x9e, 0x1b, 0x93, 0x0b, 0x41, 0xb2, 0x1c, 0xad, 0x26, - 0x91, 0x17, 0x34, 0xb8, 0x91, 0x73, 0x49, 0x36, 0x83, 0x75, 0x8b, 0xf6, 0x57, 0xac, 0xac, 0x90, - 0x52, 0xa3, 0x13, 0x39, 0x09, 0x69, 0xec, 0xa0, 0x8f, 0x40, 0x85, 0x9e, 0x1b, 0xe5, 0xa8, 0xdc, - 0x28, 0x52, 0x72, 0x1a, 0x33, 0xa1, 0x85, 0x28, 0xfd, 0x17, 0x63, 0x4e, 0xd4, 0xfe, 0x6a, 0x2d, - 0xab, 0x2c, 0xb0, 0xbb, 0xf9, 0xf3, 0x00, 0x8d, 0x70, 0x8d, 0x34, 0x5b, 0x3e, 0x1d, 0x16, 0x8b, - 0x5d, 0xf0, 0x28, 0x53, 0xc9, 0xbc, 0x82, 0x60, 0x03, 0x0b, 0xfd, 0xb2, 0x05, 0xd0, 0x90, 0x6b, - 0x5e, 0x2a, 0x02, 0xd7, 0x8a, 0xfc, 0x1c, 0xbd, 0xa3, 0x74, 0x5f, 0x14, 0x41, 0x6c, 0x10, 0x47, - 0xbf, 0x60, 0x41, 0x35, 0x91, 0xdd, 0xe7, 0xa2, 0x71, 0xad, 0xc8, 0x9e, 0xc8, 0x8f, 0xd6, 0x3a, - 0x91, 0x1a, 0x12, 0x45, 0x17, 0xfd, 0xa2, 0x05, 0x10, 0xef, 0x04, 0xee, 0x4a, 0xe8, 0x7b, 0xee, - 0x8e, 0x90, 0x98, 0xd7, 0x0b, 0x35, 0xe7, 0xa8, 0xd6, 0x67, 0x46, 0xe8, 0x68, 0xe8, 0xff, 0xd8, - 0xa0, 0x8c, 0x3e, 0x06, 0xd5, 0x58, 0x2c, 0x37, 0x21, 0x23, 0xd7, 0x8a, 0x35, 0x2a, 0xf1, 0xb6, - 0x05, 0x7b, 0x15, 0xff, 0xb0, 0xa2, 0x89, 0xfe, 0xa6, 0x05, 0xa3, 0xad, 0xb4, 0x99, 0x50, 0x88, - 0xc3, 0xe2, 0x78, 0x40, 0xc6, 0x0c, 0xc9, 0xad, 0x2d, 0x99, 0x42, 0x9c, 0xed, 0x05, 0xe5, 0x80, - 0x7a, 0x05, 0x2f, 0xb7, 0xb8, 0xc9, 0x72, 0x40, 0x73, 0xc0, 0xf9, 0x2c, 0x10, 0x77, 0xe2, 0xa3, - 0x15, 0x38, 0x45, 0x7b, 0xb7, 0xc3, 0xd5, 0x4f, 0x29, 0x5e, 0x62, 0x26, 0x0c, 0xab, 0x33, 0x8f, - 0x88, 0x15, 0xc2, 0xee, 0x3a, 0xb2, 0x38, 0x38, 0xb7, 0x26, 0xfa, 0x23, 0x0b, 0x1e, 0xf1, 0x98, - 0x18, 0x30, 0x0d, 0xf6, 0x5a, 0x22, 0x88, 0x8b, 0x76, 0x52, 0x28, 0xaf, 0xe8, 0x26, 0x7e, 0x66, - 0x7e, 0x5c, 0x7c, 0xc1, 0x23, 0x0b, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xf4, 0x53, 0x30, 0x2c, - 0xf7, 0xc5, 0x0a, 0x65, 0xc1, 0x4c, 0xd0, 0xd6, 0x66, 0xc6, 0xee, 0xec, 0x4e, 0x0c, 0xaf, 0x99, - 0x00, 0x9c, 0xc6, 0xb3, 0xff, 0x4d, 0x39, 0x75, 0x4b, 0xa4, 0x6c, 0x98, 0x8c, 0xdd, 0xb8, 0xd2, - 0xfe, 0x23, 0xb9, 0x67, 0xa1, 0xec, 0x46, 0x59, 0x97, 0x34, 0xbb, 0x51, 0x45, 0x31, 0x36, 0x88, - 0x53, 0xa5, 0x74, 0xcc, 0xc9, 0x5a, 0x4a, 0x05, 0x07, 0x7c, 0xb9, 0xc8, 0x2e, 0x75, 0xde, 0xe9, - 0x9d, 0x11, 0x5d, 0x1b, 0xeb, 0x00, 0xe1, 0xce, 0x2e, 0xa1, 0x8f, 0x42, 0x2d, 0x52, 0x9e, 0x2d, - 0xe5, 0x22, 0x8e, 0x6a, 0x72, 0xd9, 0x88, 0xee, 0xa8, 0x0b, 0x20, 0xed, 0xc3, 0xa2, 0x29, 0xda, - 0x7f, 0x98, 0xbe, 0x18, 0x33, 0x78, 0x47, 0x0f, 0x97, 0x7e, 0x5f, 0xb0, 0x60, 0x30, 0x0a, 0x7d, - 0xdf, 0x0b, 0x1a, 0x94, 0xcf, 0x09, 0x61, 0xfd, 0xc1, 0x23, 0x91, 0x97, 0x82, 0xa1, 0x31, 0xcd, - 0x1a, 0x6b, 0x9a, 0xd8, 0xec, 0x80, 0xfd, 0x67, 0x16, 0x8c, 0x77, 0xe3, 0xc7, 0x88, 0xc0, 0x5b, - 0x25, 0xb3, 0x51, 0x43, 0xb1, 0x1c, 0xcc, 0x11, 0x9f, 0x28, 0xb3, 0x79, 0x75, 0xe6, 0x71, 0xf1, - 0x99, 0x6f, 0x5d, 0xe9, 0x8e, 0x8a, 0xf7, 0x6a, 0x07, 0xbd, 0x04, 0x27, 0x8c, 0xef, 0x8a, 0xd5, - 0xc0, 0xd4, 0x66, 0x26, 0xa9, 0x02, 0x34, 0x9d, 0x81, 0xdd, 0xdd, 0x9d, 0x78, 0x28, 0x5b, 0x26, - 0x04, 0x46, 0x47, 0x3b, 0xf6, 0x6f, 0x94, 0xb2, 0xb3, 0xa5, 0x64, 0xfd, 0x1b, 0x56, 0x87, 0x35, - 0xe1, 0xfd, 0x47, 0x21, 0x5f, 0x99, 0xdd, 0x41, 0xb9, 0x61, 0x74, 0xc7, 0xb9, 0x8f, 0xd7, 0xf6, - 0xf6, 0xbf, 0xed, 0x83, 0x3d, 0x7a, 0xd6, 0x83, 0xf2, 0x7e, 0xe0, 0x7b, 0xd4, 0xcf, 0x59, 0xea, - 0xc2, 0x8c, 0xef, 0xe1, 0xfa, 0x51, 0x8d, 0x3d, 0x3f, 0x3f, 0xc5, 0xdc, 0x75, 0x44, 0x59, 0xd1, - 0xd3, 0x57, 0x73, 0xe8, 0x6b, 0x56, 0xfa, 0xca, 0x8f, 0x3b, 0x35, 0x7a, 0x47, 0xd6, 0x27, 0xe3, - 0x1e, 0x91, 0x77, 0x4c, 0xdf, 0x3e, 0x75, 0xbb, 0x61, 0x9c, 0x04, 0xd8, 0xf0, 0x02, 0xc7, 0xf7, - 0x5e, 0xa3, 0xa7, 0xa3, 0x0a, 0x13, 0xf0, 0x4c, 0x63, 0xba, 0xa8, 0x4a, 0xb1, 0x81, 0x71, 0xf6, - 0xaf, 0xc2, 0xa0, 0xf1, 0xe5, 0x39, 0x1e, 0x2f, 0xa7, 0x4c, 0x8f, 0x97, 0x9a, 0xe1, 0xa8, 0x72, - 0xf6, 0xbd, 0x70, 0x22, 0xdb, 0xc1, 0x83, 0xd4, 0xb7, 0xff, 0xf7, 0x40, 0xf6, 0x0e, 0x6e, 0x8d, - 0x44, 0x4d, 0xda, 0xb5, 0x37, 0x0d, 0x5b, 0x6f, 0x1a, 0xb6, 0xde, 0x34, 0x6c, 0x99, 0x77, 0x13, - 0xc2, 0x68, 0x33, 0x70, 0x4c, 0x46, 0x9b, 0x94, 0x19, 0xaa, 0x5a, 0xb8, 0x19, 0xca, 0xfe, 0x74, - 0x87, 0xe5, 0x7e, 0x2d, 0x22, 0x04, 0x85, 0x50, 0x09, 0xc2, 0x3a, 0x91, 0x3a, 0xee, 0xe5, 0x62, - 0x14, 0xb6, 0xab, 0x61, 0xdd, 0x70, 0x17, 0xa7, 0xff, 0x62, 0xcc, 0xe9, 0xd8, 0x77, 0x2a, 0x90, - 0x52, 0x27, 0xf9, 0xbc, 0xbf, 0x1d, 0x06, 0x22, 0xd2, 0x0a, 0xaf, 0xe1, 0x45, 0x21, 0xcb, 0x74, - 0x44, 0x09, 0x2f, 0xc6, 0x12, 0x4e, 0x65, 0x5e, 0xcb, 0x49, 0x36, 0x85, 0x30, 0x53, 0x32, 0x6f, - 0xc5, 0x49, 0x36, 0x31, 0x83, 0xa0, 0xf7, 0xc2, 0x48, 0x92, 0xba, 0x0a, 0x17, 0x57, 0xbe, 0x0f, - 0x09, 0xdc, 0x91, 0xf4, 0x45, 0x39, 0xce, 0x60, 0xa3, 0x57, 0xa1, 0x6f, 0x93, 0xf8, 0x4d, 0x31, - 0xf5, 0xab, 0xc5, 0xc9, 0x1a, 0xf6, 0xad, 0x97, 0x88, 0xdf, 0xe4, 0x9c, 0x90, 0xfe, 0xc2, 0x8c, - 0x14, 0x5d, 0xf7, 0xb5, 0xad, 0x76, 0x9c, 0x84, 0x4d, 0xef, 0x35, 0x69, 0xe9, 0x7c, 0x7f, 0xc1, - 0x84, 0xaf, 0xc8, 0xf6, 0xb9, 0x49, 0x49, 0xfd, 0xc5, 0x9a, 0x32, 0xeb, 0x47, 0xdd, 0x8b, 0xd8, - 0x92, 0xd9, 0x11, 0x06, 0xcb, 0xa2, 0xfb, 0x31, 0x27, 0xdb, 0xe7, 0xfd, 0x50, 0x7f, 0xb1, 0xa6, - 0x8c, 0x76, 0xd4, 0xfe, 0x1b, 0x64, 0x7d, 0xb8, 0x56, 0x70, 0x1f, 0xf8, 0xde, 0xcb, 0xdd, 0x87, - 0x8f, 0x43, 0xc5, 0xdd, 0x74, 0xa2, 0x64, 0x7c, 0x88, 0x2d, 0x1a, 0xb5, 0x8a, 0x67, 0x69, 0x21, - 0xe6, 0x30, 0xf4, 0x28, 0x94, 0x23, 0xb2, 0xc1, 0xbc, 0x93, 0x0d, 0xbf, 0x28, 0x4c, 0x36, 0x30, - 0x2d, 0xb7, 0x7f, 0xad, 0x94, 0x56, 0xdb, 0xd2, 0xdf, 0xcd, 0x57, 0xbb, 0xdb, 0x8e, 0x62, 0x69, - 0xfe, 0x32, 0x56, 0x3b, 0x2b, 0xc6, 0x12, 0x8e, 0x3e, 0x61, 0xc1, 0xc0, 0xcd, 0x38, 0x0c, 0x02, - 0x92, 0x08, 0x11, 0x79, 0xbd, 0xe0, 0xa1, 0xb8, 0xcc, 0x5b, 0xd7, 0x7d, 0x10, 0x05, 0x58, 0xd2, - 0xa5, 0xdd, 0x25, 0xb7, 0x5d, 0xbf, 0x5d, 0xef, 0x70, 0x75, 0xb9, 0xc0, 0x8b, 0xb1, 0x84, 0x53, - 0x54, 0x2f, 0xe0, 0xa8, 0x7d, 0x69, 0xd4, 0x85, 0x40, 0xa0, 0x0a, 0xb8, 0xfd, 0xcd, 0x01, 0x38, - 0x9d, 0xbb, 0x39, 0xa8, 0x42, 0xc5, 0x54, 0x96, 0x8b, 0x9e, 0x4f, 0xa4, 0x93, 0x17, 0x53, 0xa8, - 0xae, 0xab, 0x52, 0x6c, 0x60, 0xa0, 0x9f, 0x07, 0x68, 0x39, 0x91, 0xd3, 0x24, 0xca, 0x3c, 0x7d, - 0x68, 0xbd, 0x85, 0xf6, 0x63, 0x45, 0xb6, 0xa9, 0x8f, 0xe8, 0xaa, 0x28, 0xc6, 0x06, 0x49, 0xf4, - 0x1c, 0x0c, 0x46, 0xc4, 0x27, 0x4e, 0xcc, 0x9c, 0xdb, 0xb3, 0x91, 0x3a, 0x58, 0x83, 0xb0, 0x89, - 0x87, 0x9e, 0x50, 0xfe, 0x70, 0x19, 0xbf, 0xa0, 0xb4, 0x4f, 0x1c, 0x7a, 0xdd, 0x82, 0x91, 0x0d, - 0xcf, 0x27, 0x9a, 0xba, 0x88, 0xab, 0x59, 0x3e, 0xfc, 0x47, 0x5e, 0x34, 0xdb, 0xd5, 0x1c, 0x32, - 0x55, 0x1c, 0xe3, 0x0c, 0x79, 0x3a, 0xcd, 0xdb, 0x24, 0x62, 0xac, 0xb5, 0x3f, 0x3d, 0xcd, 0xd7, - 0x79, 0x31, 0x96, 0x70, 0x34, 0x0d, 0xa3, 0x2d, 0x27, 0x8e, 0x67, 0x23, 0x52, 0x27, 0x41, 0xe2, - 0x39, 0x3e, 0x8f, 0x7a, 0xa9, 0x6a, 0x67, 0xf1, 0x95, 0x34, 0x18, 0x67, 0xf1, 0xd1, 0x07, 0xe0, - 0x61, 0x6e, 0xff, 0x59, 0xf2, 0xe2, 0xd8, 0x0b, 0x1a, 0x7a, 0x19, 0x08, 0x33, 0xd8, 0x84, 0x68, - 0xea, 0xe1, 0x85, 0x7c, 0x34, 0xdc, 0xad, 0x3e, 0x7a, 0x0a, 0xaa, 0xf1, 0x96, 0xd7, 0x9a, 0x8d, - 0xea, 0x31, 0xbb, 0xfb, 0xa9, 0x6a, 0xa3, 0xeb, 0xaa, 0x28, 0xc7, 0x0a, 0x03, 0xb9, 0x30, 0xc4, - 0xa7, 0x84, 0x3b, 0xf4, 0x09, 0xfe, 0xf8, 0x74, 0x57, 0x31, 0x2d, 0x82, 0x38, 0x27, 0xb1, 0x73, - 0xeb, 0x82, 0xbc, 0x89, 0xe2, 0x17, 0x27, 0xd7, 0x8d, 0x66, 0x70, 0xaa, 0xd1, 0xf4, 0x89, 0x6d, - 0xb0, 0x87, 0x13, 0xdb, 0x73, 0x30, 0xb8, 0xd5, 0x5e, 0x27, 0x62, 0xe4, 0x05, 0xdb, 0x52, 0xab, - 0xef, 0x8a, 0x06, 0x61, 0x13, 0x8f, 0xf9, 0x52, 0xb6, 0x3c, 0xf1, 0x2f, 0x1e, 0x1f, 0x36, 0x7c, - 0x29, 0x57, 0x16, 0x64, 0x31, 0x36, 0x71, 0xec, 0x5f, 0x29, 0xa5, 0x8d, 0x12, 0x26, 0xff, 0x40, - 0x31, 0xe5, 0x12, 0xc9, 0x75, 0x27, 0x92, 0xba, 0xc4, 0x21, 0xe3, 0x86, 0x44, 0xbb, 0xd7, 0x9d, - 0xc8, 0xe4, 0x37, 0x8c, 0x00, 0x96, 0x94, 0xd0, 0x4d, 0xe8, 0x4b, 0x7c, 0xa7, 0xa0, 0x40, 0x43, - 0x83, 0xa2, 0xb6, 0x11, 0x2d, 0x4e, 0xc7, 0x98, 0xd1, 0x40, 0x8f, 0xd0, 0x83, 0xd1, 0xba, 0xbc, - 0xc4, 0x12, 0x67, 0x99, 0xf5, 0x18, 0xb3, 0x52, 0xfb, 0xcf, 0x07, 0x73, 0x58, 0xbe, 0x92, 0xb1, - 0xe8, 0x3c, 0x00, 0x9d, 0xb1, 0x95, 0x88, 0x6c, 0x78, 0xb7, 0x85, 0x8e, 0xa3, 0xd8, 0xca, 0x55, - 0x05, 0xc1, 0x06, 0x96, 0xac, 0xb3, 0xda, 0xde, 0xa0, 0x75, 0x4a, 0x9d, 0x75, 0x38, 0x04, 0x1b, - 0x58, 0xe8, 0x59, 0xe8, 0xf7, 0x9a, 0x4e, 0x43, 0xf9, 0xd8, 0x3e, 0x42, 0xf9, 0xc9, 0x02, 0x2b, - 0xb9, 0xbb, 0x3b, 0x31, 0xa2, 0x3a, 0xc4, 0x8a, 0xb0, 0xc0, 0x45, 0xbf, 0x61, 0xc1, 0x90, 0x1b, - 0x36, 0x9b, 0x61, 0xc0, 0x4f, 0xa6, 0xe2, 0x98, 0x7d, 0xf3, 0xa8, 0x34, 0x90, 0xc9, 0x59, 0x83, - 0x18, 0x3f, 0x67, 0xab, 0x88, 0x48, 0x13, 0x84, 0x53, 0xbd, 0x32, 0xd9, 0x4e, 0x65, 0x1f, 0xb6, - 0xf3, 0x9b, 0x16, 0x8c, 0xf1, 0xba, 0xc6, 0x81, 0x59, 0x04, 0xff, 0x85, 0x47, 0xfc, 0x59, 0x1d, - 0x36, 0x04, 0x65, 0x47, 0xed, 0x80, 0xe3, 0xce, 0x4e, 0xa2, 0x79, 0x18, 0xdb, 0x08, 0x23, 0x97, - 0x98, 0x03, 0x21, 0x78, 0xa6, 0x6a, 0xe8, 0x62, 0x16, 0x01, 0x77, 0xd6, 0x41, 0xd7, 0xe1, 0x21, - 0xa3, 0xd0, 0x1c, 0x07, 0xce, 0x36, 0x1f, 0x13, 0xad, 0x3d, 0x74, 0x31, 0x17, 0x0b, 0x77, 0xa9, - 0x9d, 0xe6, 0x50, 0xb5, 0x1e, 0x38, 0xd4, 0x2b, 0x70, 0xc6, 0xed, 0x1c, 0x99, 0xed, 0xb8, 0xbd, - 0x1e, 0x73, 0x26, 0x5a, 0x9d, 0xf9, 0x31, 0xd1, 0xc0, 0x99, 0xd9, 0x6e, 0x88, 0xb8, 0x7b, 0x1b, - 0xe8, 0x23, 0x50, 0x8d, 0x08, 0x9b, 0x95, 0x58, 0x44, 0xc2, 0x1d, 0xd2, 0x90, 0xa0, 0x95, 0x63, - 0xde, 0xac, 0x16, 0x0b, 0xa2, 0x20, 0xc6, 0x8a, 0x22, 0xba, 0x05, 0x03, 0x2d, 0x27, 0x71, 0x37, - 0x45, 0xfc, 0xdb, 0xa1, 0xcd, 0xde, 0x8a, 0x38, 0xbb, 0xa5, 0x30, 0x22, 0xe6, 0x39, 0x11, 0x2c, - 0xa9, 0x51, 0x45, 0xc9, 0x0d, 0x9b, 0xad, 0x30, 0x20, 0x41, 0x22, 0x39, 0xf8, 0x08, 0xbf, 0x4a, - 0x90, 0xa5, 0xd8, 0xc0, 0x40, 0x2b, 0x70, 0x8a, 0x99, 0xd5, 0x6e, 0x78, 0xc9, 0x66, 0xd8, 0x4e, - 0xe4, 0x29, 0x71, 0x7c, 0x24, 0x7d, 0x99, 0xb4, 0x98, 0x83, 0x83, 0x73, 0x6b, 0x66, 0x65, 0xcf, - 0xe8, 0xbd, 0xc9, 0x9e, 0x13, 0xfb, 0xcb, 0x9e, 0xb3, 0xef, 0x83, 0xb1, 0x0e, 0xa6, 0x71, 0x20, - 0xdb, 0xd9, 0x1c, 0x3c, 0x94, 0xbf, 0x3d, 0x0f, 0x64, 0x41, 0xfb, 0xa7, 0x19, 0x17, 0x6a, 0xe3, - 0x34, 0xd1, 0x83, 0x35, 0xd6, 0x81, 0x32, 0x09, 0xb6, 0x85, 0xb4, 0xba, 0x78, 0xb8, 0x55, 0x72, - 0x21, 0xd8, 0xe6, 0xdc, 0x85, 0x99, 0x9c, 0x2e, 0x04, 0xdb, 0x98, 0xb6, 0x8d, 0xbe, 0x64, 0xa5, - 0xb4, 0x61, 0x6e, 0xc3, 0xfd, 0xd0, 0x91, 0x1c, 0x9f, 0x7a, 0x56, 0x90, 0xed, 0x7f, 0x57, 0x82, - 0x73, 0xfb, 0x35, 0xd2, 0xc3, 0xf0, 0x3d, 0x0e, 0xfd, 0x31, 0x73, 0x8a, 0x10, 0xec, 0x7f, 0x90, - 0xee, 0x0a, 0xee, 0x26, 0xf1, 0x0a, 0x16, 0x20, 0xe4, 0x43, 0xb9, 0xe9, 0xb4, 0x84, 0x69, 0x6f, - 0xe1, 0xb0, 0xa1, 0x66, 0xf4, 0xbf, 0xe3, 0x2f, 0x39, 0x2d, 0xbe, 0x3c, 0x8d, 0x02, 0x4c, 0xc9, - 0xa0, 0x04, 0x2a, 0x4e, 0x14, 0x39, 0xf2, 0x06, 0xfe, 0x4a, 0x31, 0xf4, 0xa6, 0x69, 0x93, 0xfc, - 0x02, 0x33, 0x55, 0x84, 0x39, 0x31, 0xfb, 0x73, 0x03, 0xa9, 0xb8, 0x24, 0xe6, 0x56, 0x11, 0x43, - 0xbf, 0xb0, 0xe8, 0x59, 0x45, 0x47, 0xf8, 0xf1, 0xc0, 0x5f, 0x76, 0x58, 0x16, 0xe9, 0x13, 0x04, - 0x29, 0xf4, 0x59, 0x8b, 0x25, 0x29, 0x90, 0xc1, 0x5e, 0xe2, 0x88, 0x7a, 0x34, 0x39, 0x13, 0xcc, - 0xd4, 0x07, 0xb2, 0x10, 0x9b, 0xd4, 0x45, 0xb2, 0x11, 0xa6, 0x9a, 0x77, 0x26, 0x1b, 0x61, 0xaa, - 0xb6, 0x84, 0xa3, 0xdb, 0x39, 0xee, 0x13, 0x05, 0x04, 0xba, 0xf7, 0xe0, 0x30, 0xf1, 0x35, 0x0b, - 0xc6, 0xbc, 0xec, 0x3d, 0xb8, 0x38, 0xd0, 0xdd, 0x28, 0xc6, 0xfc, 0xd6, 0x79, 0xcd, 0xae, 0x14, - 0x87, 0x0e, 0x10, 0xee, 0xec, 0x0c, 0xaa, 0x43, 0x9f, 0x17, 0x6c, 0x84, 0x42, 0x5d, 0x9a, 0x39, - 0x5c, 0xa7, 0x16, 0x82, 0x8d, 0x50, 0xef, 0x66, 0xfa, 0x0f, 0xb3, 0xd6, 0xd1, 0x22, 0x9c, 0x92, - 0xa1, 0x29, 0x97, 0xbc, 0x38, 0x09, 0xa3, 0x9d, 0x45, 0xaf, 0xe9, 0x25, 0x4c, 0xd5, 0x29, 0xcf, - 0x8c, 0x53, 0x49, 0x84, 0x73, 0xe0, 0x38, 0xb7, 0x16, 0x7a, 0x0d, 0x06, 0xe4, 0xdd, 0x73, 0xb5, - 0x88, 0xc3, 0x71, 0xe7, 0xfa, 0x57, 0x8b, 0x69, 0x55, 0x5c, 0x3e, 0x4b, 0x82, 0xf6, 0xeb, 0x83, - 0xd0, 0x79, 0x45, 0x9e, 0xbe, 0x0f, 0xb7, 0x8e, 0xfb, 0x3e, 0x9c, 0x1e, 0x8d, 0x62, 0x7d, 0x95, - 0x5d, 0xc0, 0xda, 0x16, 0x54, 0xf5, 0x35, 0xe5, 0x4e, 0xe0, 0x62, 0x46, 0x03, 0x45, 0xd0, 0xbf, - 0x49, 0x1c, 0x3f, 0xd9, 0x2c, 0xe6, 0x46, 0xe5, 0x12, 0x6b, 0x2b, 0x1b, 0x4f, 0xc6, 0x4b, 0xb1, - 0xa0, 0x84, 0x6e, 0xc3, 0xc0, 0x26, 0x5f, 0x00, 0xe2, 0xb4, 0xb2, 0x74, 0xd8, 0xc1, 0x4d, 0xad, - 0x2a, 0x3d, 0xdd, 0xa2, 0x00, 0x4b, 0x72, 0xcc, 0xf7, 0xca, 0xf0, 0x0e, 0xe1, 0x5b, 0xb7, 0xb8, - 0x50, 0xba, 0xde, 0x5d, 0x43, 0x3e, 0x0c, 0x43, 0x11, 0x71, 0xc3, 0xc0, 0xf5, 0x7c, 0x52, 0x9f, - 0x96, 0xb7, 0x25, 0x07, 0x89, 0xa0, 0x62, 0xc6, 0x08, 0x6c, 0xb4, 0x81, 0x53, 0x2d, 0xa2, 0xcf, - 0x58, 0x30, 0xa2, 0xa2, 0xaa, 0xe9, 0x84, 0x10, 0x61, 0x15, 0x5f, 0x2c, 0x28, 0x86, 0x9b, 0xb5, - 0x39, 0x83, 0xee, 0xec, 0x4e, 0x8c, 0xa4, 0xcb, 0x70, 0x86, 0x2e, 0x7a, 0x09, 0x20, 0x5c, 0xe7, - 0x0e, 0x56, 0xd3, 0x89, 0x30, 0x91, 0x1f, 0xe4, 0x53, 0x47, 0x78, 0x24, 0xa6, 0x6c, 0x01, 0x1b, - 0xad, 0xa1, 0x2b, 0x00, 0x7c, 0xdb, 0xac, 0xed, 0xb4, 0xe4, 0x91, 0x46, 0x86, 0xc0, 0xc1, 0xaa, - 0x82, 0xdc, 0xdd, 0x9d, 0xe8, 0x34, 0x59, 0x32, 0x2f, 0x12, 0xa3, 0x3a, 0xfa, 0x39, 0x18, 0x88, - 0xdb, 0xcd, 0xa6, 0xa3, 0x0c, 0xe8, 0x05, 0xc6, 0x76, 0xf2, 0x76, 0x0d, 0x56, 0xc4, 0x0b, 0xb0, - 0xa4, 0x88, 0x6e, 0x52, 0xa6, 0x1a, 0x0b, 0x5b, 0x2a, 0xdb, 0x45, 0x5c, 0x27, 0xe0, 0x86, 0xa4, - 0x77, 0x49, 0x15, 0x1f, 0xe7, 0xe0, 0xdc, 0xdd, 0x9d, 0x78, 0x28, 0x5d, 0xbe, 0x18, 0x8a, 0x68, - 0xcb, 0xdc, 0x36, 0xd1, 0x65, 0x99, 0x64, 0x89, 0x7e, 0xb6, 0xcc, 0xfd, 0xf1, 0xa4, 0x4e, 0xb2, - 0xc4, 0x8a, 0xbb, 0x8f, 0x99, 0x59, 0x19, 0x2d, 0xc1, 0x49, 0x37, 0x0c, 0x92, 0x28, 0xf4, 0x7d, - 0x9e, 0x64, 0x8c, 0x9f, 0x2e, 0xb9, 0x81, 0xfd, 0xad, 0xa2, 0xdb, 0x27, 0x67, 0x3b, 0x51, 0x70, - 0x5e, 0x3d, 0x3b, 0x48, 0x5f, 0x76, 0x89, 0xc1, 0x79, 0x16, 0x86, 0xc8, 0xed, 0x84, 0x44, 0x81, - 0xe3, 0x5f, 0xc3, 0x8b, 0xd2, 0xb4, 0xcc, 0xf6, 0xc0, 0x05, 0xa3, 0x1c, 0xa7, 0xb0, 0x90, 0xad, - 0x4c, 0x2a, 0x46, 0x04, 0x31, 0x37, 0xa9, 0x48, 0x03, 0x8a, 0xfd, 0xcd, 0x72, 0x4a, 0x21, 0xbb, - 0x2f, 0x57, 0x6b, 0x2c, 0x55, 0x8d, 0xcc, 0xe9, 0xc3, 0x00, 0xe2, 0xa0, 0x51, 0x24, 0x65, 0x95, - 0xaa, 0x66, 0xd9, 0x24, 0x84, 0xd3, 0x74, 0xd1, 0x16, 0x54, 0x36, 0xc3, 0x38, 0x91, 0xc7, 0x8f, - 0x43, 0x9e, 0x74, 0x2e, 0x85, 0x71, 0xc2, 0xb4, 0x08, 0xf5, 0xd9, 0xb4, 0x24, 0xc6, 0x9c, 0x06, - 0x3d, 0x83, 0xc6, 0x9b, 0x4e, 0x54, 0x8f, 0x67, 0x59, 0xbc, 0x7f, 0x1f, 0x53, 0x1f, 0x94, 0xb2, - 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xb3, 0xff, 0xab, 0x95, 0xba, 0x7f, 0xb8, 0xc1, 0x9c, 0xb7, 0xb7, - 0x49, 0x40, 0xb9, 0x81, 0xe9, 0x2e, 0xf6, 0x53, 0x99, 0x50, 0xd8, 0xb7, 0x75, 0x4b, 0xbd, 0x77, - 0x8b, 0xb6, 0x30, 0xc9, 0x9a, 0x30, 0x3c, 0xcb, 0x3e, 0x6e, 0xa5, 0x63, 0x9a, 0x4b, 0x45, 0x9c, - 0x4b, 0xcc, 0xb8, 0xfe, 0x7d, 0xc3, 0xa3, 0xed, 0x2f, 0x59, 0x30, 0x30, 0xe3, 0xb8, 0x5b, 0xe1, - 0xc6, 0x06, 0x7a, 0x0a, 0xaa, 0xf5, 0x76, 0x64, 0x86, 0x57, 0x2b, 0xcb, 0xc6, 0x9c, 0x28, 0xc7, - 0x0a, 0x83, 0x2e, 0xfd, 0x0d, 0xc7, 0x95, 0xd1, 0xfd, 0x65, 0xbe, 0xf4, 0x2f, 0xb2, 0x12, 0x2c, - 0x20, 0x74, 0xf8, 0x9b, 0xce, 0x6d, 0x59, 0x39, 0x7b, 0xf9, 0xb1, 0xa4, 0x41, 0xd8, 0xc4, 0xb3, - 0xff, 0x95, 0x05, 0xe3, 0x33, 0x4e, 0xec, 0xb9, 0xd3, 0xed, 0x64, 0x73, 0xc6, 0x4b, 0xd6, 0xdb, - 0xee, 0x16, 0x49, 0x78, 0x16, 0x08, 0xda, 0xcb, 0x76, 0x4c, 0x77, 0xa0, 0x3a, 0x0e, 0xaa, 0x5e, - 0x5e, 0x13, 0xe5, 0x58, 0x61, 0xa0, 0xd7, 0x60, 0xb0, 0xe5, 0xc4, 0xf1, 0xad, 0x30, 0xaa, 0x63, - 0xb2, 0x51, 0x4c, 0x9e, 0x98, 0x55, 0xe2, 0x46, 0x24, 0xc1, 0x64, 0x43, 0x38, 0x0a, 0xe8, 0xf6, - 0xb1, 0x49, 0xcc, 0xfe, 0x65, 0x0b, 0x4e, 0xcd, 0x10, 0x27, 0x22, 0x11, 0x4b, 0x2b, 0xa3, 0x3e, - 0x04, 0xbd, 0x0a, 0xd5, 0x84, 0x96, 0xd0, 0x1e, 0x59, 0xc5, 0xf6, 0x88, 0x5d, 0xf1, 0xaf, 0x89, - 0xc6, 0xb1, 0x22, 0x63, 0x7f, 0xc1, 0x82, 0x33, 0x79, 0x7d, 0x99, 0xf5, 0xc3, 0x76, 0xfd, 0x7e, - 0x74, 0xe8, 0x6f, 0x59, 0x30, 0xc4, 0xae, 0x4d, 0xe7, 0x48, 0xe2, 0x78, 0x7e, 0x47, 0x4a, 0x3b, - 0xab, 0xc7, 0x94, 0x76, 0xe7, 0xa0, 0x6f, 0x33, 0x6c, 0x92, 0xec, 0x95, 0xff, 0xa5, 0xb0, 0x49, - 0x30, 0x83, 0xa0, 0x67, 0xe8, 0x22, 0xf4, 0x82, 0xc4, 0xa1, 0xdb, 0x51, 0xda, 0xbe, 0x47, 0xf9, - 0x02, 0x54, 0xc5, 0xd8, 0xc4, 0xb1, 0xff, 0x65, 0x0d, 0x06, 0x84, 0x7f, 0x4a, 0xcf, 0x59, 0x49, - 0xa4, 0x89, 0xa2, 0xd4, 0xd5, 0x44, 0x11, 0x43, 0xbf, 0xcb, 0x72, 0x6b, 0x0a, 0x4d, 0xf8, 0x4a, - 0x21, 0x0e, 0x4d, 0x3c, 0x5d, 0xa7, 0xee, 0x16, 0xff, 0x8f, 0x05, 0x29, 0xf4, 0x45, 0x0b, 0x46, - 0xdd, 0x30, 0x08, 0x88, 0xab, 0xd5, 0xb4, 0xbe, 0x22, 0xfc, 0x56, 0x66, 0xd3, 0x8d, 0xea, 0x3b, - 0xbb, 0x0c, 0x00, 0x67, 0xc9, 0xa3, 0x17, 0x60, 0x98, 0x8f, 0xd9, 0xf5, 0x94, 0xc1, 0x5e, 0x67, - 0x3a, 0x33, 0x81, 0x38, 0x8d, 0x8b, 0x26, 0xf9, 0xc5, 0x87, 0xc8, 0x29, 0xd6, 0xaf, 0xed, 0x9a, - 0x46, 0x36, 0x31, 0x03, 0x03, 0x45, 0x80, 0x22, 0xb2, 0x11, 0x91, 0x78, 0x53, 0xf8, 0xef, 0x30, - 0x15, 0x71, 0xe0, 0xde, 0xf2, 0x09, 0xe0, 0x8e, 0x96, 0x70, 0x4e, 0xeb, 0x68, 0x4b, 0x9c, 0x91, - 0xab, 0x45, 0xf0, 0x73, 0x31, 0xcd, 0x5d, 0x8f, 0xca, 0x13, 0x50, 0x61, 0xa2, 0x8b, 0xa9, 0xa6, - 0x65, 0x1e, 0xc3, 0xc6, 0x04, 0x1b, 0xe6, 0xe5, 0x68, 0x0e, 0x4e, 0x64, 0xf2, 0xb4, 0xc5, 0xc2, - 0xb0, 0xae, 0xe2, 0x95, 0x32, 0x19, 0xde, 0x62, 0xdc, 0x51, 0xc3, 0xb4, 0x9f, 0x0c, 0xee, 0x63, - 0x3f, 0xd9, 0x51, 0x5e, 0xa2, 0xdc, 0xe4, 0xfd, 0x62, 0x21, 0x03, 0xd0, 0x93, 0x4b, 0xe8, 0xe7, - 0x33, 0x2e, 0xa1, 0xc3, 0xac, 0x03, 0xd7, 0x8b, 0xe9, 0xc0, 0xc1, 0xfd, 0x3f, 0xef, 0xa7, 0x3f, - 0xe7, 0xff, 0xb2, 0x40, 0xce, 0xeb, 0xac, 0xe3, 0x6e, 0x12, 0xba, 0x64, 0xd0, 0x7b, 0x61, 0x44, - 0x59, 0x01, 0xb8, 0x4a, 0x64, 0xb1, 0x55, 0xa3, 0x2e, 0xf7, 0x71, 0x0a, 0x8a, 0x33, 0xd8, 0x68, - 0x0a, 0x6a, 0x74, 0x9c, 0x78, 0x55, 0x2e, 0xf7, 0x95, 0xa5, 0x61, 0x7a, 0x65, 0x41, 0xd4, 0xd2, - 0x38, 0x28, 0x84, 0x31, 0xdf, 0x89, 0x13, 0xd6, 0x83, 0xd5, 0x9d, 0xc0, 0xbd, 0xc7, 0x6c, 0x1e, - 0x2c, 0x28, 0x66, 0x31, 0xdb, 0x10, 0xee, 0x6c, 0xdb, 0xfe, 0x6e, 0x1f, 0x0c, 0xa7, 0x38, 0xe3, - 0x01, 0x15, 0x86, 0xa7, 0xa0, 0x2a, 0x65, 0x78, 0x36, 0x6d, 0x91, 0x12, 0xf4, 0x0a, 0x83, 0x0a, - 0xad, 0x75, 0x2d, 0x55, 0xb3, 0x0a, 0x8e, 0x21, 0x70, 0xb1, 0x89, 0xc7, 0x98, 0x72, 0xe2, 0xc7, - 0xb3, 0xbe, 0x47, 0x82, 0x84, 0x77, 0xb3, 0x18, 0xa6, 0xbc, 0xb6, 0xb8, 0x6a, 0x36, 0xaa, 0x99, - 0x72, 0x06, 0x80, 0xb3, 0xe4, 0xd1, 0xa7, 0x2c, 0x18, 0x76, 0x6e, 0xc5, 0x3a, 0x01, 0xb4, 0x70, - 0xfe, 0x3c, 0xa4, 0x90, 0x4a, 0xe5, 0x94, 0xe6, 0x56, 0xeb, 0x54, 0x11, 0x4e, 0x13, 0x45, 0x6f, - 0x58, 0x80, 0xc8, 0x6d, 0xe2, 0x4a, 0xf7, 0x54, 0xd1, 0x97, 0xfe, 0x22, 0x0e, 0xcb, 0x17, 0x3a, - 0xda, 0xe5, 0x5c, 0xbd, 0xb3, 0x1c, 0xe7, 0xf4, 0xc1, 0xfe, 0x17, 0x65, 0xb5, 0xa1, 0xb4, 0x47, - 0xb4, 0x63, 0x78, 0x66, 0x5a, 0xf7, 0xee, 0x99, 0xa9, 0x3d, 0x4b, 0x3a, 0x83, 0x84, 0x53, 0x31, - 0x85, 0xa5, 0xfb, 0x14, 0x53, 0xf8, 0x0b, 0x56, 0x2a, 0x41, 0xd7, 0xe0, 0xf9, 0x97, 0x8a, 0xf5, - 0xc6, 0x9e, 0xe4, 0x5e, 0x2f, 0x19, 0xee, 0x9e, 0x76, 0x76, 0xa2, 0xdc, 0xd4, 0x40, 0x3b, 0x10, - 0x37, 0xfc, 0x0f, 0x65, 0x18, 0x34, 0x24, 0x69, 0xae, 0x5a, 0x64, 0x3d, 0x60, 0x6a, 0x51, 0xe9, - 0x00, 0x6a, 0xd1, 0xcf, 0x43, 0xcd, 0x95, 0x5c, 0xbe, 0x98, 0x14, 0xe2, 0x59, 0xd9, 0xa1, 0x19, - 0xbd, 0x2a, 0xc2, 0x9a, 0x26, 0x9a, 0x4f, 0x45, 0xa2, 0xa5, 0xce, 0xdb, 0x79, 0xa1, 0x62, 0x42, - 0x52, 0x74, 0xd6, 0xc9, 0xde, 0xff, 0x56, 0x7a, 0xf0, 0x3d, 0xfa, 0xae, 0xa5, 0x26, 0xf7, 0x18, - 0x52, 0x8e, 0xdc, 0x4c, 0xa7, 0x1c, 0xb9, 0x50, 0xc8, 0x30, 0x77, 0xc9, 0x35, 0x72, 0x15, 0x06, - 0x66, 0xc3, 0x66, 0xd3, 0x09, 0xea, 0xe8, 0x27, 0x60, 0xc0, 0xe5, 0x3f, 0x85, 0x6d, 0x8a, 0xdd, - 0x70, 0x0a, 0x28, 0x96, 0x30, 0xf4, 0x08, 0xf4, 0x39, 0x51, 0x43, 0xda, 0xa3, 0x98, 0x27, 0xd2, - 0x74, 0xd4, 0x88, 0x31, 0x2b, 0xb5, 0xff, 0x49, 0x1f, 0x30, 0x07, 0x00, 0x27, 0x22, 0xf5, 0xb5, - 0x90, 0x65, 0xfe, 0x3c, 0xd2, 0x7b, 0x41, 0x7d, 0x58, 0x7a, 0x90, 0xef, 0x06, 0x8d, 0xfb, 0xa1, - 0xf2, 0x31, 0xdf, 0x0f, 0x75, 0xb9, 0xf2, 0xeb, 0x7b, 0x80, 0xae, 0xfc, 0xec, 0xcf, 0x59, 0x80, - 0x94, 0xd7, 0x88, 0xbe, 0x93, 0x9f, 0x82, 0x9a, 0xf2, 0x1f, 0x11, 0x8a, 0x95, 0x66, 0x11, 0x12, - 0x80, 0x35, 0x4e, 0x0f, 0x27, 0xe4, 0xc7, 0x25, 0xff, 0x2e, 0xa7, 0xfd, 0xab, 0x19, 0xd7, 0x17, - 0xec, 0xdc, 0xfe, 0xbd, 0x12, 0x3c, 0xc4, 0x45, 0xf2, 0x92, 0x13, 0x38, 0x0d, 0xd2, 0xa4, 0xbd, - 0xea, 0xd5, 0xcb, 0xc2, 0xa5, 0x47, 0x33, 0x4f, 0xfa, 0x4b, 0x1f, 0x76, 0xef, 0xf2, 0x3d, 0xc7, - 0x77, 0xd9, 0x42, 0xe0, 0x25, 0x98, 0x35, 0x8e, 0x62, 0xa8, 0xca, 0xf7, 0x35, 0x04, 0x2f, 0x2e, - 0x88, 0x90, 0x62, 0x4b, 0x42, 0x6e, 0x12, 0xac, 0x08, 0x51, 0xc5, 0xd5, 0x0f, 0xdd, 0x2d, 0x4c, - 0x5a, 0x21, 0xe3, 0xbb, 0x86, 0xbb, 0xea, 0xa2, 0x28, 0xc7, 0x0a, 0xc3, 0x6e, 0xc2, 0xa8, 0x1c, - 0xc3, 0xd6, 0x15, 0xb2, 0x83, 0xc9, 0x06, 0x95, 0x3f, 0xae, 0x2c, 0x32, 0x9e, 0xfc, 0x50, 0xf2, - 0x67, 0xd6, 0x04, 0xe2, 0x34, 0xae, 0x4c, 0x06, 0x5a, 0xca, 0x4f, 0x06, 0x6a, 0xff, 0x9e, 0x05, - 0x59, 0x01, 0x68, 0xa4, 0x3e, 0xb4, 0xf6, 0x4c, 0x7d, 0x78, 0x80, 0xe4, 0x81, 0x3f, 0x0b, 0x83, - 0x4e, 0x42, 0x75, 0x16, 0x7e, 0xca, 0x2f, 0xdf, 0xdb, 0x45, 0xd0, 0x52, 0x58, 0xf7, 0x36, 0x3c, - 0x76, 0xba, 0x37, 0x9b, 0xb3, 0xff, 0xb2, 0x0f, 0xc6, 0x3a, 0x82, 0x99, 0xd0, 0xf3, 0x30, 0xa4, - 0x86, 0x42, 0xda, 0xcf, 0x6a, 0xa6, 0xcb, 0xa2, 0x86, 0xe1, 0x14, 0x66, 0x0f, 0xfb, 0x61, 0x01, - 0x4e, 0x46, 0xe4, 0xd5, 0x36, 0x69, 0x93, 0xe9, 0x8d, 0x84, 0x44, 0xab, 0xc4, 0x0d, 0x83, 0x3a, - 0x4f, 0xd0, 0x59, 0x9e, 0x79, 0xf8, 0xce, 0xee, 0xc4, 0x49, 0xdc, 0x09, 0xc6, 0x79, 0x75, 0x50, - 0x0b, 0x86, 0x7d, 0x53, 0xe5, 0x14, 0xe7, 0x8d, 0x7b, 0xd2, 0x56, 0xd5, 0x92, 0x48, 0x15, 0xe3, - 0x34, 0x81, 0xb4, 0xde, 0x5a, 0xb9, 0x4f, 0x7a, 0xeb, 0x27, 0xb5, 0xde, 0xca, 0x3d, 0x16, 0x3e, - 0x58, 0x70, 0x30, 0xdb, 0x51, 0x2b, 0xae, 0x2f, 0x42, 0x55, 0x7a, 0x73, 0xf5, 0xe4, 0x05, 0x65, - 0xb6, 0xd3, 0x85, 0x81, 0x3e, 0x01, 0x3f, 0x7e, 0x21, 0x8a, 0x8c, 0xc1, 0xbc, 0x1a, 0x26, 0xd3, - 0xbe, 0x1f, 0xde, 0xa2, 0x3a, 0xc1, 0xb5, 0x98, 0x08, 0x83, 0x8e, 0x7d, 0xb7, 0x04, 0x39, 0x67, - 0x23, 0xba, 0x1f, 0xb5, 0x22, 0x92, 0xda, 0x8f, 0x07, 0x53, 0x46, 0xd0, 0x6d, 0xee, 0xf1, 0xc6, - 0x45, 0xee, 0x07, 0x8a, 0x3e, 0xdb, 0x69, 0x27, 0x38, 0xc5, 0x8e, 0x94, 0x23, 0xdc, 0x79, 0x00, - 0xad, 0x3f, 0x8a, 0x08, 0x0b, 0x75, 0xa1, 0xae, 0xd5, 0x4c, 0x6c, 0x60, 0xd1, 0xa3, 0xbe, 0x17, - 0xc4, 0x89, 0xe3, 0xfb, 0x97, 0xbc, 0x20, 0x11, 0x36, 0x4b, 0xa5, 0x5b, 0x2c, 0x68, 0x10, 0x36, - 0xf1, 0xce, 0xbe, 0xcb, 0x98, 0xbf, 0x83, 0xcc, 0xfb, 0x26, 0x9c, 0x99, 0xf7, 0x12, 0x15, 0x17, - 0xa4, 0xd6, 0x1b, 0x55, 0x0f, 0x55, 0x9c, 0x9b, 0xd5, 0x35, 0xce, 0xcd, 0x88, 0xcb, 0x29, 0xa5, - 0xc3, 0x88, 0xb2, 0x71, 0x39, 0xf6, 0xf3, 0x70, 0x6a, 0xde, 0x4b, 0x2e, 0x7a, 0x3e, 0x39, 0x20, - 0x11, 0xfb, 0x77, 0xfb, 0x61, 0xc8, 0x8c, 0x70, 0x3d, 0x48, 0xa8, 0xde, 0x17, 0xa8, 0x06, 0x28, - 0xbe, 0xce, 0x53, 0xd7, 0x91, 0x37, 0x0e, 0x1d, 0x6e, 0x9b, 0x3f, 0x62, 0x86, 0x12, 0xa8, 0x69, - 0x62, 0xb3, 0x03, 0xe8, 0x16, 0x54, 0x36, 0x58, 0xdc, 0x48, 0xb9, 0x08, 0x9f, 0x8d, 0xbc, 0x11, - 0xd5, 0xdb, 0x91, 0x47, 0x9e, 0x70, 0x7a, 0x54, 0x70, 0x47, 0xe9, 0x60, 0x44, 0xc3, 0xa1, 0x58, - 0x84, 0x21, 0x2a, 0x8c, 0x6e, 0x22, 0xa1, 0x72, 0x0f, 0x22, 0x21, 0xc5, 0xa0, 0xfb, 0xef, 0x13, - 0x83, 0x66, 0x31, 0x40, 0xc9, 0x26, 0x53, 0x2b, 0x45, 0x04, 0xc4, 0x00, 0x1b, 0x04, 0x23, 0x06, - 0x28, 0x05, 0xc6, 0x59, 0x7c, 0xf4, 0x31, 0xc5, 0xe2, 0xab, 0x45, 0x98, 0x7b, 0xcd, 0x15, 0x7d, - 0xd4, 0xdc, 0xfd, 0x73, 0x25, 0x18, 0x99, 0x0f, 0xda, 0x2b, 0xf3, 0x2b, 0xed, 0x75, 0xdf, 0x73, - 0xaf, 0x90, 0x1d, 0xca, 0xc2, 0xb7, 0xc8, 0xce, 0xc2, 0x9c, 0xd8, 0x41, 0x6a, 0xcd, 0x5c, 0xa1, - 0x85, 0x98, 0xc3, 0x28, 0x33, 0xda, 0xf0, 0x82, 0x06, 0x89, 0x5a, 0x91, 0x27, 0x2c, 0xb1, 0x06, - 0x33, 0xba, 0xa8, 0x41, 0xd8, 0xc4, 0xa3, 0x6d, 0x87, 0xb7, 0x02, 0x12, 0x65, 0xf5, 0xeb, 0x65, - 0x5a, 0x88, 0x39, 0x8c, 0x22, 0x25, 0x51, 0x3b, 0x4e, 0xc4, 0x62, 0x54, 0x48, 0x6b, 0xb4, 0x10, - 0x73, 0x18, 0xdd, 0xe9, 0x71, 0x7b, 0x9d, 0xb9, 0xc4, 0x64, 0xc2, 0x2d, 0x56, 0x79, 0x31, 0x96, - 0x70, 0x8a, 0xba, 0x45, 0x76, 0xe6, 0xe8, 0x61, 0x3c, 0x13, 0x10, 0x76, 0x85, 0x17, 0x63, 0x09, - 0x67, 0x29, 0x44, 0xd3, 0xc3, 0xf1, 0x43, 0x97, 0x42, 0x34, 0xdd, 0xfd, 0x2e, 0xc7, 0xfa, 0x5f, - 0xb7, 0x60, 0xc8, 0x74, 0x64, 0x43, 0x8d, 0x8c, 0x2e, 0xbc, 0xdc, 0x91, 0x81, 0xfa, 0x3d, 0x79, - 0xaf, 0x33, 0x36, 0xbc, 0x24, 0x6c, 0xc5, 0x4f, 0x93, 0xa0, 0xe1, 0x05, 0x84, 0x39, 0x1a, 0x70, - 0x07, 0xb8, 0x94, 0x97, 0xdc, 0x6c, 0x58, 0x27, 0xf7, 0xa0, 0x4c, 0xdb, 0x37, 0x60, 0xac, 0x23, - 0x0a, 0xb0, 0x07, 0x15, 0x64, 0xdf, 0x18, 0x6c, 0x1b, 0xc3, 0x20, 0x6d, 0x58, 0xa6, 0xb1, 0x9a, - 0x85, 0x31, 0xbe, 0x91, 0x28, 0xa5, 0x55, 0x77, 0x93, 0x34, 0x55, 0x64, 0x27, 0x33, 0xfb, 0x5f, - 0xcf, 0x02, 0x71, 0x27, 0xbe, 0xfd, 0x79, 0x0b, 0x86, 0x53, 0x81, 0x99, 0x05, 0x29, 0x4b, 0x6c, - 0xa7, 0x85, 0xcc, 0xaf, 0x92, 0x39, 0x97, 0x97, 0x99, 0x30, 0xd5, 0x3b, 0x4d, 0x83, 0xb0, 0x89, - 0x67, 0x7f, 0xa9, 0x04, 0x55, 0xe9, 0x9b, 0xd2, 0x43, 0x57, 0x3e, 0x6b, 0xc1, 0xb0, 0xba, 0x6a, - 0x61, 0x36, 0xbc, 0x52, 0x11, 0xa1, 0x2a, 0xb4, 0x07, 0xca, 0x0a, 0x10, 0x6c, 0x84, 0x5a, 0x73, - 0xc7, 0x26, 0x31, 0x9c, 0xa6, 0x8d, 0xae, 0x03, 0xc4, 0x3b, 0x71, 0x42, 0x9a, 0x86, 0x35, 0xd1, - 0x36, 0x76, 0xdc, 0xa4, 0x1b, 0x46, 0x84, 0xee, 0xaf, 0xab, 0x61, 0x9d, 0xac, 0x2a, 0x4c, 0xad, - 0x42, 0xe9, 0x32, 0x6c, 0xb4, 0x64, 0xff, 0xa3, 0x12, 0x9c, 0xc8, 0x76, 0x09, 0x7d, 0x10, 0x86, - 0x24, 0x75, 0xe3, 0xd4, 0x29, 0x3d, 0x6b, 0x86, 0xb0, 0x01, 0xbb, 0xbb, 0x3b, 0x31, 0xd1, 0xf9, - 0xd2, 0xe7, 0xa4, 0x89, 0x82, 0x53, 0x8d, 0xf1, 0xfb, 0x2e, 0x71, 0x31, 0x3b, 0xb3, 0x33, 0xdd, - 0x6a, 0x89, 0x4b, 0x2b, 0xe3, 0xbe, 0xcb, 0x84, 0xe2, 0x0c, 0x36, 0x5a, 0x81, 0x53, 0x46, 0xc9, - 0x55, 0xe2, 0x35, 0x36, 0xd7, 0xc3, 0x48, 0x9e, 0xc0, 0x1e, 0xd1, 0x2e, 0x73, 0x9d, 0x38, 0x38, - 0xb7, 0x26, 0x95, 0xf6, 0xae, 0xd3, 0x72, 0x5c, 0x2f, 0xd9, 0x11, 0xe6, 0x51, 0xc5, 0x9b, 0x66, - 0x45, 0x39, 0x56, 0x18, 0xf6, 0x12, 0xf4, 0xf5, 0xb8, 0x82, 0x7a, 0xd2, 0xfc, 0x5f, 0x84, 0x2a, - 0x6d, 0x4e, 0xaa, 0x77, 0x45, 0x34, 0x19, 0x42, 0x55, 0xbe, 0x9b, 0x84, 0x6c, 0x28, 0x7b, 0x8e, - 0xbc, 0x52, 0x54, 0x9f, 0xb5, 0x10, 0xc7, 0x6d, 0x76, 0x98, 0xa6, 0x40, 0xf4, 0x38, 0x94, 0xc9, - 0xed, 0x56, 0xf6, 0xee, 0xf0, 0xc2, 0xed, 0x96, 0x17, 0x91, 0x98, 0x22, 0x91, 0xdb, 0x2d, 0x74, - 0x16, 0x4a, 0x5e, 0x5d, 0x08, 0x29, 0x10, 0x38, 0xa5, 0x85, 0x39, 0x5c, 0xf2, 0xea, 0xf6, 0x6d, - 0xa8, 0xa9, 0x87, 0x9a, 0xd0, 0x96, 0xe4, 0xdd, 0x56, 0x11, 0xce, 0x64, 0xb2, 0xdd, 0x2e, 0x5c, - 0xbb, 0x0d, 0xa0, 0xc3, 0x40, 0x8b, 0xe2, 0x2f, 0xe7, 0xa0, 0xcf, 0x0d, 0x45, 0xf4, 0x7c, 0x55, - 0x37, 0xc3, 0x98, 0x36, 0x83, 0xd8, 0x37, 0x60, 0xe4, 0x4a, 0x10, 0xde, 0x62, 0xef, 0x29, 0xb0, - 0xf4, 0x81, 0xb4, 0xe1, 0x0d, 0xfa, 0x23, 0xab, 0x22, 0x30, 0x28, 0xe6, 0x30, 0x95, 0xd8, 0xac, - 0xd4, 0x2d, 0xb1, 0x99, 0xfd, 0x71, 0x0b, 0x86, 0x54, 0x3c, 0xd9, 0xfc, 0xf6, 0x16, 0x6d, 0xb7, - 0x11, 0x85, 0xed, 0x56, 0xb6, 0x5d, 0xf6, 0x26, 0x1c, 0xe6, 0x30, 0x33, 0xd0, 0xb2, 0xb4, 0x4f, - 0xa0, 0xe5, 0x39, 0xe8, 0xdb, 0xf2, 0x82, 0x7a, 0xf6, 0x6d, 0xa0, 0x2b, 0x5e, 0x50, 0xc7, 0x0c, - 0x42, 0xbb, 0x70, 0x42, 0x75, 0x41, 0x0a, 0x84, 0xe7, 0x61, 0x68, 0xbd, 0xed, 0xf9, 0x75, 0x99, - 0x17, 0x31, 0x63, 0x51, 0x99, 0x31, 0x60, 0x38, 0x85, 0x49, 0xcf, 0x75, 0xeb, 0x5e, 0xe0, 0x44, - 0x3b, 0x2b, 0x5a, 0x02, 0x29, 0xa6, 0x34, 0xa3, 0x20, 0xd8, 0xc0, 0xb2, 0x5f, 0x2f, 0xc3, 0x48, - 0x3a, 0xaa, 0xae, 0x87, 0xe3, 0xd5, 0xe3, 0x50, 0x61, 0x81, 0x76, 0xd9, 0xa9, 0xe5, 0xa9, 0x04, - 0x39, 0x0c, 0xc5, 0xd0, 0xcf, 0xb3, 0x87, 0x14, 0xf3, 0xae, 0x96, 0xea, 0xa4, 0xb2, 0xc3, 0x30, - 0x97, 0x3b, 0x91, 0xb0, 0x44, 0x90, 0x42, 0x9f, 0xb2, 0x60, 0x20, 0x6c, 0x99, 0x09, 0xb1, 0x3e, - 0x50, 0x64, 0xc4, 0xa1, 0x08, 0x43, 0x12, 0x1a, 0xb1, 0x9a, 0x7a, 0x39, 0x1d, 0x92, 0xf4, 0xd9, - 0x77, 0xc3, 0x90, 0x89, 0xb9, 0x9f, 0x52, 0x5c, 0x35, 0x95, 0xe2, 0xcf, 0x9a, 0x8b, 0x42, 0xc4, - 0x54, 0xf6, 0xb0, 0xdd, 0xae, 0x41, 0xc5, 0x55, 0x7e, 0x09, 0xf7, 0x94, 0x4d, 0x57, 0xa5, 0xf3, - 0x60, 0x77, 0x53, 0xbc, 0x35, 0xfb, 0xbb, 0x96, 0xb1, 0x3e, 0x30, 0x89, 0x17, 0xea, 0x28, 0x82, - 0x72, 0x63, 0x7b, 0x4b, 0xa8, 0xa2, 0x97, 0x0b, 0x1a, 0xde, 0xf9, 0xed, 0x2d, 0xbd, 0xc6, 0xcd, - 0x52, 0x4c, 0x89, 0xf5, 0x60, 0x2c, 0x4c, 0x85, 0xde, 0x96, 0xf7, 0x0f, 0xbd, 0xb5, 0xdf, 0x28, - 0xc1, 0x58, 0xc7, 0xa2, 0x42, 0xaf, 0x41, 0x25, 0xa2, 0x5f, 0x29, 0x3e, 0x6f, 0xb1, 0xb0, 0x60, - 0xd9, 0x78, 0xa1, 0xae, 0xe5, 0x6e, 0xba, 0x1c, 0x73, 0x92, 0xe8, 0x32, 0x20, 0xed, 0x3d, 0xa3, - 0x2c, 0x95, 0xfc, 0x93, 0xcf, 0x8a, 0xaa, 0x68, 0xba, 0x03, 0x03, 0xe7, 0xd4, 0x42, 0x2f, 0x64, - 0x0d, 0x9e, 0xe5, 0xb4, 0x39, 0x7b, 0x2f, 0xdb, 0xa5, 0xfd, 0xdb, 0x25, 0x18, 0x4e, 0xe5, 0x27, - 0x43, 0x3e, 0x54, 0x89, 0xcf, 0xee, 0x1a, 0xa4, 0xb0, 0x39, 0x6c, 0xb6, 0x71, 0x25, 0x20, 0x2f, - 0x88, 0x76, 0xb1, 0xa2, 0xf0, 0x60, 0xdc, 0xf9, 0x3f, 0x0f, 0x43, 0xb2, 0x43, 0x1f, 0x70, 0x9a, - 0xbe, 0x18, 0x40, 0xb5, 0x46, 0x2f, 0x18, 0x30, 0x9c, 0xc2, 0xb4, 0x7f, 0xbf, 0x0c, 0xe3, 0xfc, - 0x72, 0xa6, 0xae, 0x56, 0xde, 0x92, 0x3c, 0x6f, 0xfd, 0x35, 0x9d, 0x45, 0xd0, 0x2a, 0xe2, 0x49, - 0xcd, 0x6e, 0x84, 0x7a, 0x72, 0x18, 0xfb, 0x6a, 0xc6, 0x61, 0x8c, 0xab, 0xdd, 0x8d, 0x23, 0xea, - 0xd1, 0x0f, 0x97, 0x07, 0xd9, 0xdf, 0x2f, 0xc1, 0x68, 0xe6, 0xe5, 0x14, 0xf4, 0x7a, 0x3a, 0xd9, - 0xb6, 0x55, 0x84, 0x4d, 0x7d, 0xcf, 0xc7, 0x34, 0x0e, 0x96, 0x72, 0xfb, 0x3e, 0x6d, 0x15, 0xfb, - 0x3b, 0x25, 0x18, 0x49, 0x3f, 0xf9, 0xf2, 0x00, 0x8e, 0xd4, 0x3b, 0xa0, 0xc6, 0x5e, 0x35, 0x60, - 0x2f, 0x15, 0x73, 0x93, 0x3c, 0x4f, 0x20, 0x2f, 0x0b, 0xb1, 0x86, 0x3f, 0x10, 0x99, 0xcc, 0xed, - 0x7f, 0x68, 0xc1, 0x69, 0xfe, 0x95, 0xd9, 0x75, 0xf8, 0xd7, 0xf3, 0x46, 0xf7, 0xe5, 0x62, 0x3b, - 0x98, 0xc9, 0x7e, 0xb9, 0xdf, 0xf8, 0xb2, 0x87, 0x45, 0x45, 0x6f, 0xd3, 0x4b, 0xe1, 0x01, 0xec, - 0xec, 0x81, 0x16, 0x83, 0xfd, 0x9d, 0x32, 0xe8, 0xb7, 0x54, 0x91, 0x27, 0xa2, 0x47, 0x0b, 0xc9, - 0x02, 0xba, 0xba, 0x13, 0xb8, 0xfa, 0xd5, 0xd6, 0x6a, 0x26, 0x78, 0xf4, 0x97, 0x2c, 0x18, 0xf4, - 0x02, 0x2f, 0xf1, 0x1c, 0x76, 0x8c, 0x2e, 0xe6, 0x41, 0x44, 0x45, 0x6e, 0x81, 0xb7, 0x1c, 0x46, - 0xe6, 0x3d, 0x8e, 0x22, 0x86, 0x4d, 0xca, 0xe8, 0xc3, 0xc2, 0xa7, 0xbb, 0x5c, 0x58, 0xdc, 0x73, - 0x35, 0xe3, 0xc8, 0xdd, 0xa2, 0x8a, 0x57, 0x12, 0x15, 0x94, 0x2e, 0x00, 0xd3, 0xa6, 0x54, 0x42, - 0x69, 0xfd, 0x3c, 0x3f, 0x2d, 0xc6, 0x9c, 0x90, 0x1d, 0x03, 0xea, 0x1c, 0x8b, 0x03, 0xfa, 0xcb, - 0x4e, 0x41, 0xcd, 0x69, 0x27, 0x61, 0x93, 0x0e, 0x93, 0xb8, 0x6a, 0xd2, 0x1e, 0xc1, 0x12, 0x80, - 0x35, 0x8e, 0xfd, 0x7a, 0x05, 0x32, 0xe1, 0x9c, 0xe8, 0xb6, 0xf9, 0x0e, 0xb0, 0x55, 0xec, 0x3b, - 0xc0, 0xaa, 0x33, 0x79, 0x6f, 0x01, 0xa3, 0x06, 0x54, 0x5a, 0x9b, 0x4e, 0x2c, 0xd5, 0xea, 0x17, - 0xd5, 0x39, 0x8e, 0x16, 0xde, 0xdd, 0x9d, 0xf8, 0x99, 0xde, 0xac, 0xae, 0x74, 0xad, 0x4e, 0xf1, - 0x14, 0x34, 0x9a, 0x34, 0x6b, 0x03, 0xf3, 0xf6, 0x0f, 0xf2, 0x24, 0xe4, 0x27, 0xc4, 0xf3, 0x0d, - 0x98, 0xc4, 0x6d, 0x3f, 0x11, 0xab, 0xe1, 0xc5, 0x02, 0x77, 0x19, 0x6f, 0x58, 0x27, 0x22, 0xe0, - 0xff, 0xb1, 0x41, 0x14, 0x7d, 0x10, 0x6a, 0x71, 0xe2, 0x44, 0xc9, 0x3d, 0x86, 0x0e, 0xab, 0x41, - 0x5f, 0x95, 0x8d, 0x60, 0xdd, 0x1e, 0x7a, 0x89, 0x25, 0x45, 0xf6, 0xe2, 0xcd, 0x7b, 0x0c, 0xc5, - 0x90, 0x09, 0x94, 0x45, 0x0b, 0xd8, 0x68, 0x0d, 0x9d, 0x07, 0x60, 0x6b, 0x9b, 0xfb, 0x1f, 0x56, - 0x99, 0x95, 0x49, 0xb1, 0x42, 0xac, 0x20, 0xd8, 0xc0, 0xb2, 0x7f, 0x12, 0xd2, 0x99, 0x34, 0xd0, - 0x84, 0x4c, 0xdc, 0xc1, 0xad, 0xd0, 0x2c, 0xa4, 0x22, 0x95, 0x63, 0xe3, 0x37, 0x2d, 0x30, 0xd3, - 0x7d, 0xa0, 0x57, 0x79, 0x5e, 0x11, 0xab, 0x88, 0x9b, 0x43, 0xa3, 0xdd, 0xc9, 0x25, 0xa7, 0x95, - 0xb9, 0xc2, 0x96, 0xc9, 0x45, 0xce, 0xbe, 0x0b, 0xaa, 0x12, 0x7a, 0x20, 0xa5, 0xee, 0x63, 0x70, - 0x52, 0x86, 0x67, 0x4a, 0xbb, 0xa9, 0xb8, 0x75, 0xda, 0xdf, 0xf4, 0x23, 0xed, 0x39, 0xa5, 0x6e, - 0xf6, 0x9c, 0x1e, 0x5e, 0x83, 0xfe, 0x2d, 0x0b, 0xce, 0x65, 0x3b, 0x10, 0x2f, 0x85, 0x81, 0x97, - 0x84, 0xd1, 0x2a, 0x49, 0x12, 0x2f, 0x68, 0xb0, 0x74, 0x6a, 0xb7, 0x9c, 0x48, 0x66, 0xab, 0x67, - 0x8c, 0xf2, 0x86, 0x13, 0x05, 0x98, 0x95, 0xa2, 0x1d, 0xe8, 0xe7, 0x4e, 0x6a, 0x42, 0x5b, 0x3f, - 0xe4, 0xde, 0xc8, 0x19, 0x0e, 0x7d, 0x5c, 0xe0, 0x0e, 0x72, 0x58, 0x10, 0xb4, 0xbf, 0x6f, 0x01, - 0x5a, 0xde, 0x26, 0x51, 0xe4, 0xd5, 0x0d, 0xb7, 0x3a, 0xf6, 0x0c, 0x92, 0xf1, 0xdc, 0x91, 0x19, - 0x3c, 0x9c, 0x79, 0x06, 0xc9, 0xf8, 0x97, 0xff, 0x0c, 0x52, 0xe9, 0x60, 0xcf, 0x20, 0xa1, 0x65, - 0x38, 0xdd, 0xe4, 0xc7, 0x0d, 0xfe, 0xb4, 0x08, 0x3f, 0x7b, 0xa8, 0x38, 0xb7, 0x33, 0x77, 0x76, - 0x27, 0x4e, 0x2f, 0xe5, 0x21, 0xe0, 0xfc, 0x7a, 0xf6, 0xbb, 0x00, 0x71, 0x6f, 0xba, 0xd9, 0x3c, - 0x5f, 0xa5, 0xae, 0xe6, 0x17, 0xfb, 0x2b, 0x15, 0x18, 0xcd, 0xe4, 0x32, 0xa6, 0x47, 0xbd, 0x4e, - 0xe7, 0xa8, 0x43, 0xcb, 0xef, 0xce, 0xee, 0xf5, 0xe4, 0x6e, 0x15, 0x40, 0xc5, 0x0b, 0x5a, 0xed, - 0xa4, 0x98, 0x30, 0x5b, 0xde, 0x89, 0x05, 0xda, 0xa0, 0x61, 0x2e, 0xa6, 0x7f, 0x31, 0x27, 0x53, - 0xa4, 0xf3, 0x56, 0x4a, 0x19, 0xef, 0xbb, 0x4f, 0xe6, 0x80, 0x4f, 0x68, 0x57, 0xaa, 0x4a, 0x11, - 0x86, 0xc5, 0xcc, 0x62, 0x39, 0xea, 0xab, 0xf6, 0x6f, 0x96, 0x60, 0xd0, 0x98, 0x34, 0xf4, 0x6b, - 0xe9, 0x64, 0x58, 0x56, 0x71, 0x9f, 0xc4, 0xda, 0x9f, 0xd4, 0xe9, 0xae, 0xf8, 0x27, 0x3d, 0xd1, - 0x99, 0x07, 0xeb, 0xee, 0xee, 0xc4, 0x89, 0x4c, 0xa6, 0xab, 0x54, 0x6e, 0xac, 0xb3, 0x1f, 0x85, - 0xd1, 0x4c, 0x33, 0x39, 0x9f, 0xbc, 0x66, 0x7e, 0xf2, 0xa1, 0xcd, 0x52, 0xe6, 0x90, 0x7d, 0x83, - 0x0e, 0x99, 0x88, 0xee, 0x0b, 0x7d, 0xd2, 0x83, 0x0d, 0x36, 0x13, 0xc4, 0x5b, 0xea, 0x31, 0x88, - 0xf7, 0x49, 0xa8, 0xb6, 0x42, 0xdf, 0x73, 0x3d, 0x95, 0x9b, 0x92, 0x85, 0x0d, 0xaf, 0x88, 0x32, - 0xac, 0xa0, 0xe8, 0x16, 0xd4, 0x6e, 0xde, 0x4a, 0xf8, 0xed, 0x8f, 0xb0, 0x6f, 0x17, 0x75, 0xe9, - 0xa3, 0x94, 0x16, 0x75, 0xbd, 0x84, 0x35, 0x2d, 0x64, 0x43, 0x3f, 0x13, 0x82, 0x32, 0x22, 0x81, - 0xd9, 0xde, 0x99, 0x74, 0x8c, 0xb1, 0x80, 0xd8, 0x5f, 0xaf, 0xc1, 0xa9, 0xbc, 0x84, 0xf2, 0xe8, - 0x23, 0xd0, 0xcf, 0xfb, 0x58, 0xcc, 0x9b, 0x25, 0x79, 0x34, 0xe6, 0x59, 0x83, 0xa2, 0x5b, 0xec, - 0x37, 0x16, 0x34, 0x05, 0x75, 0xdf, 0x59, 0x17, 0x2b, 0xe4, 0x68, 0xa8, 0x2f, 0x3a, 0x9a, 0xfa, - 0xa2, 0xc3, 0xa9, 0xfb, 0xce, 0x3a, 0xba, 0x0d, 0x95, 0x86, 0x97, 0x10, 0x47, 0x18, 0x11, 0x6e, - 0x1c, 0x09, 0x71, 0xe2, 0x70, 0x2d, 0x8d, 0xfd, 0xc4, 0x9c, 0x20, 0xfa, 0x9a, 0x05, 0xa3, 0xeb, - 0xe9, 0xec, 0x01, 0x82, 0x79, 0x3a, 0x47, 0xf0, 0x68, 0x40, 0x9a, 0x10, 0x7f, 0x07, 0x2c, 0x53, - 0x88, 0xb3, 0xdd, 0x41, 0x9f, 0xb4, 0x60, 0x60, 0xc3, 0xf3, 0x8d, 0xbc, 0xcd, 0x47, 0x30, 0x39, - 0x17, 0x19, 0x01, 0x7d, 0xe2, 0xe0, 0xff, 0x63, 0x2c, 0x29, 0x77, 0x93, 0x54, 0xfd, 0x87, 0x95, - 0x54, 0x03, 0xf7, 0x49, 0x52, 0x7d, 0xc6, 0x82, 0x9a, 0x1a, 0x69, 0x11, 0x85, 0xfd, 0xc1, 0x23, - 0x9c, 0x72, 0x6e, 0x39, 0x51, 0x7f, 0xb1, 0x26, 0x8e, 0xbe, 0x68, 0xc1, 0xa0, 0xf3, 0x5a, 0x3b, - 0x22, 0x75, 0xb2, 0x1d, 0xb6, 0x62, 0xf1, 0x88, 0xe8, 0xcb, 0xc5, 0x77, 0x66, 0x9a, 0x12, 0x99, - 0x23, 0xdb, 0xcb, 0xad, 0x58, 0x44, 0x4b, 0xe9, 0x02, 0x6c, 0x76, 0xc1, 0xde, 0x2d, 0xc1, 0xc4, - 0x3e, 0x2d, 0xa0, 0xe7, 0x61, 0x28, 0x8c, 0x1a, 0x4e, 0xe0, 0xbd, 0x66, 0xa6, 0x03, 0x51, 0x5a, - 0xd6, 0xb2, 0x01, 0xc3, 0x29, 0x4c, 0x33, 0x4e, 0xbc, 0xb4, 0x4f, 0x9c, 0xf8, 0x39, 0xe8, 0x8b, - 0x48, 0x2b, 0xcc, 0x1e, 0x16, 0x58, 0xa4, 0x02, 0x83, 0xa0, 0x47, 0xa1, 0xec, 0xb4, 0x3c, 0xe1, - 0x88, 0xa6, 0xce, 0x40, 0xd3, 0x2b, 0x0b, 0x98, 0x96, 0xa7, 0xd2, 0x56, 0x54, 0x8e, 0x25, 0x6d, - 0x05, 0x15, 0x03, 0xe2, 0xee, 0xa2, 0x5f, 0x8b, 0x81, 0xf4, 0x9d, 0x82, 0xfd, 0x46, 0x19, 0x1e, - 0xdd, 0x73, 0xbd, 0x68, 0x3f, 0x3c, 0x6b, 0x0f, 0x3f, 0x3c, 0x39, 0x3c, 0xa5, 0xfd, 0x86, 0xa7, - 0xdc, 0x65, 0x78, 0x3e, 0x49, 0xb7, 0x81, 0x4c, 0xa3, 0x52, 0xcc, 0x33, 0x90, 0xdd, 0xb2, 0xb2, - 0x88, 0x1d, 0x20, 0xa1, 0x58, 0xd3, 0xa5, 0x67, 0x80, 0x54, 0x8c, 0x74, 0xa5, 0x08, 0x31, 0xd0, - 0x35, 0x95, 0x09, 0x5f, 0xfb, 0xdd, 0x02, 0xaf, 0xed, 0xdf, 0xe9, 0x83, 0xc7, 0x7b, 0xe0, 0xde, - 0xe6, 0x2a, 0xb6, 0x7a, 0x5c, 0xc5, 0x3f, 0xe4, 0xd3, 0xf4, 0xe9, 0xdc, 0x69, 0xc2, 0xc5, 0x4f, - 0xd3, 0xde, 0x33, 0x84, 0x9e, 0x82, 0xaa, 0x17, 0xc4, 0xc4, 0x6d, 0x47, 0xdc, 0x27, 0xd9, 0x08, - 0x63, 0x5a, 0x10, 0xe5, 0x58, 0x61, 0xd0, 0x33, 0x9d, 0xeb, 0xd0, 0xed, 0x3f, 0x50, 0x50, 0xec, - 0xae, 0x19, 0x11, 0xc5, 0x55, 0x8a, 0xd9, 0x69, 0xca, 0x01, 0x38, 0x19, 0xfb, 0x6f, 0x58, 0x70, - 0xb6, 0xbb, 0x88, 0x45, 0xcf, 0xc0, 0xe0, 0x7a, 0xe4, 0x04, 0xee, 0x26, 0x7b, 0x00, 0x58, 0x2e, - 0x1d, 0xf6, 0xbd, 0xba, 0x18, 0x9b, 0x38, 0x68, 0x16, 0xc6, 0xb8, 0xe7, 0x86, 0x81, 0x21, 0x23, - 0x7f, 0xef, 0xec, 0x4e, 0x8c, 0xad, 0x65, 0x81, 0xb8, 0x13, 0xdf, 0xfe, 0x41, 0x39, 0xbf, 0x5b, - 0x5c, 0x15, 0x3b, 0xc8, 0x6a, 0x16, 0x6b, 0xb5, 0xd4, 0x03, 0xc7, 0x2d, 0x1f, 0x37, 0xc7, 0xed, - 0xeb, 0xc6, 0x71, 0xd1, 0x1c, 0x9c, 0x30, 0x5e, 0x68, 0xe2, 0xd1, 0xdc, 0xdc, 0x2d, 0x59, 0xa5, - 0x38, 0x59, 0xc9, 0xc0, 0x71, 0x47, 0x8d, 0x07, 0x7c, 0xe9, 0xfd, 0x7a, 0x09, 0xce, 0x74, 0xd5, - 0x7e, 0x8f, 0x49, 0xa2, 0x98, 0xd3, 0xdf, 0x77, 0x3c, 0xd3, 0x6f, 0x4e, 0x4a, 0x65, 0xbf, 0x49, - 0xb1, 0xff, 0xa4, 0xd4, 0x75, 0x23, 0xd0, 0x93, 0xd0, 0x8f, 0xec, 0x28, 0xbd, 0x00, 0xc3, 0x4e, - 0xab, 0xc5, 0xf1, 0x98, 0x17, 0x6d, 0x26, 0xa5, 0xd2, 0xb4, 0x09, 0xc4, 0x69, 0xdc, 0x9e, 0x74, - 0x9a, 0x3f, 0xb5, 0xa0, 0x86, 0xc9, 0x06, 0xe7, 0x46, 0xe8, 0xa6, 0x18, 0x22, 0xab, 0x88, 0xfc, - 0xb1, 0x74, 0x60, 0x63, 0x8f, 0xe5, 0x55, 0xcd, 0x1b, 0xec, 0xce, 0x17, 0xbb, 0x4a, 0x07, 0x7a, - 0xb1, 0x4b, 0xbd, 0xd9, 0x54, 0xee, 0xfe, 0x66, 0x93, 0xfd, 0xbd, 0x01, 0xfa, 0x79, 0xad, 0x70, - 0x36, 0x22, 0xf5, 0x98, 0xce, 0x6f, 0x3b, 0xf2, 0xc5, 0x22, 0x51, 0xf3, 0x7b, 0x0d, 0x2f, 0x62, - 0x5a, 0x9e, 0xba, 0x20, 0x2b, 0x1d, 0x28, 0xa1, 0x4c, 0x79, 0xdf, 0x84, 0x32, 0x2f, 0xc0, 0x70, - 0x1c, 0x6f, 0xae, 0x44, 0xde, 0xb6, 0x93, 0x90, 0x2b, 0x64, 0x47, 0xe8, 0xbe, 0x3a, 0x09, 0xc4, - 0xea, 0x25, 0x0d, 0xc4, 0x69, 0x5c, 0x34, 0x0f, 0x63, 0x3a, 0xad, 0x0b, 0x89, 0x12, 0x16, 0x73, - 0xc1, 0x57, 0x82, 0x8a, 0xf8, 0xd6, 0x89, 0x60, 0x04, 0x02, 0xee, 0xac, 0x43, 0xf9, 0x69, 0xaa, - 0x90, 0x76, 0xa4, 0x3f, 0xcd, 0x4f, 0x53, 0xed, 0xd0, 0xbe, 0x74, 0xd4, 0x40, 0x4b, 0x70, 0x92, - 0x2f, 0x8c, 0xe9, 0x56, 0xcb, 0xf8, 0xa2, 0x81, 0x74, 0xde, 0xce, 0xf9, 0x4e, 0x14, 0x9c, 0x57, - 0x0f, 0x3d, 0x07, 0x83, 0xaa, 0x78, 0x61, 0x4e, 0xdc, 0xed, 0x28, 0xdb, 0x92, 0x6a, 0x66, 0xa1, - 0x8e, 0x4d, 0x3c, 0xf4, 0x01, 0x78, 0x58, 0xff, 0xe5, 0x81, 0x79, 0xfc, 0xc2, 0x73, 0x4e, 0x64, - 0xcc, 0x52, 0x2f, 0x04, 0xcd, 0xe7, 0xa2, 0xd5, 0x71, 0xb7, 0xfa, 0x68, 0x1d, 0xce, 0x2a, 0xd0, - 0x85, 0x20, 0x61, 0x51, 0x36, 0x31, 0x99, 0x71, 0x62, 0x72, 0x2d, 0xf2, 0xc5, 0x4b, 0xd3, 0xea, - 0x11, 0xd9, 0x79, 0x2f, 0xb9, 0x94, 0x87, 0x89, 0x17, 0xf1, 0x1e, 0xad, 0xa0, 0x29, 0xa8, 0x91, - 0xc0, 0x59, 0xf7, 0xc9, 0xf2, 0xec, 0x02, 0xcb, 0xbc, 0x65, 0xdc, 0xaf, 0x5e, 0x90, 0x00, 0xac, - 0x71, 0x94, 0xdf, 0xef, 0x50, 0xd7, 0x07, 0x8d, 0x57, 0xe0, 0x54, 0xc3, 0x6d, 0x51, 0x8d, 0xd0, - 0x73, 0xc9, 0xb4, 0xcb, 0xdc, 0x1c, 0xe9, 0xc4, 0xf0, 0x84, 0xaa, 0xca, 0xa9, 0x7d, 0x7e, 0x76, - 0xa5, 0x03, 0x07, 0xe7, 0xd6, 0x64, 0xee, 0xb0, 0x51, 0x78, 0x7b, 0x67, 0xfc, 0x64, 0xc6, 0x1d, - 0x96, 0x16, 0x62, 0x0e, 0x43, 0x97, 0x01, 0xb1, 0x08, 0x89, 0x4b, 0x49, 0xd2, 0x52, 0x2a, 0xe8, - 0xf8, 0x29, 0xf6, 0x49, 0xca, 0xb9, 0xef, 0x62, 0x07, 0x06, 0xce, 0xa9, 0x45, 0x35, 0x9a, 0x20, - 0x64, 0xad, 0x8f, 0x3f, 0x9c, 0xd6, 0x68, 0xae, 0xf2, 0x62, 0x2c, 0xe1, 0xf6, 0x7f, 0xb4, 0x60, - 0x58, 0x6d, 0xed, 0x63, 0x08, 0x27, 0xf2, 0xd3, 0xe1, 0x44, 0xf3, 0x87, 0x67, 0x8e, 0xac, 0xe7, - 0x5d, 0x7c, 0xd2, 0xbf, 0x39, 0x08, 0xa0, 0x19, 0xa8, 0x92, 0x5d, 0x56, 0x57, 0xd9, 0xf5, 0xc0, - 0x32, 0xaf, 0xbc, 0x8c, 0x3c, 0x95, 0xfb, 0x9b, 0x91, 0x67, 0x15, 0x4e, 0x4b, 0xcd, 0x82, 0x5f, - 0xf6, 0x5d, 0x0a, 0x63, 0xc5, 0x0b, 0xab, 0x33, 0x8f, 0x8a, 0x86, 0x4e, 0x2f, 0xe4, 0x21, 0xe1, - 0xfc, 0xba, 0x29, 0x85, 0x66, 0x60, 0x5f, 0x2d, 0x53, 0x6d, 0xff, 0xc5, 0x0d, 0xf9, 0x34, 0x4f, - 0x66, 0xfb, 0x2f, 0x5e, 0x5c, 0xc5, 0x1a, 0x27, 0x5f, 0x06, 0xd4, 0x0a, 0x92, 0x01, 0x70, 0x60, - 0x19, 0x20, 0xb9, 0xd1, 0x60, 0x57, 0x6e, 0x24, 0x2f, 0x15, 0x86, 0xba, 0x5e, 0x2a, 0xbc, 0x17, - 0x46, 0xbc, 0x60, 0x93, 0x44, 0x5e, 0x42, 0xea, 0x6c, 0x2f, 0x30, 0x4e, 0x55, 0xd5, 0x1a, 0xc0, - 0x42, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0x16, 0x3a, 0xd2, 0x03, 0x0b, 0xed, 0x22, 0xb8, 0x46, 0x8b, - 0x11, 0x5c, 0x27, 0x0e, 0x2f, 0xb8, 0xc6, 0x8e, 0x54, 0x70, 0xa1, 0x42, 0x04, 0x57, 0x4f, 0x32, - 0xc1, 0x38, 0x99, 0x9e, 0xda, 0xe7, 0x64, 0xda, 0x4d, 0x6a, 0x9d, 0xbe, 0x67, 0xa9, 0x95, 0x2f, - 0x90, 0x1e, 0x3a, 0x6a, 0x81, 0xf4, 0x99, 0x12, 0x9c, 0xd6, 0x2c, 0x9b, 0x6e, 0x14, 0x6f, 0x83, - 0x32, 0x2d, 0xf6, 0x10, 0x1c, 0xbf, 0xa3, 0x33, 0x02, 0xe1, 0x74, 0x4c, 0x9d, 0x82, 0x60, 0x03, - 0x8b, 0xc5, 0x93, 0x91, 0x88, 0x65, 0x95, 0xce, 0xf2, 0xf3, 0x59, 0x51, 0x8e, 0x15, 0x06, 0x5d, - 0x8a, 0xf4, 0xb7, 0x88, 0xd1, 0xcd, 0xe6, 0x2b, 0x9c, 0xd5, 0x20, 0x6c, 0xe2, 0xa1, 0x27, 0x39, - 0x11, 0xc6, 0x4b, 0x28, 0x4f, 0x1f, 0x12, 0x8f, 0x67, 0x4b, 0xf6, 0xa1, 0xa0, 0xb2, 0x3b, 0x2c, - 0x70, 0xb0, 0xd2, 0xd9, 0x1d, 0xe6, 0xee, 0xa6, 0x30, 0xec, 0xff, 0x69, 0xc1, 0x99, 0xdc, 0xa1, - 0x38, 0x06, 0x39, 0x7d, 0x3b, 0x2d, 0xa7, 0x57, 0x8b, 0x3a, 0xc4, 0x18, 0x5f, 0xd1, 0x45, 0x66, - 0xff, 0x7b, 0x0b, 0x46, 0x34, 0xfe, 0x31, 0x7c, 0xaa, 0x97, 0xfe, 0xd4, 0xe2, 0xce, 0x6b, 0xb5, - 0x8e, 0x6f, 0xfb, 0xfd, 0x12, 0xa8, 0x1c, 0xa2, 0xd3, 0xae, 0xcc, 0xd0, 0xbc, 0xcf, 0xad, 0xf1, - 0x0e, 0xf4, 0xb3, 0x4b, 0xef, 0xb8, 0x18, 0x87, 0x9e, 0x34, 0x7d, 0x76, 0x81, 0xae, 0x1d, 0x0a, - 0xd8, 0xdf, 0x18, 0x0b, 0x82, 0x2c, 0xe7, 0xb9, 0x17, 0x53, 0xc6, 0x5f, 0x17, 0x21, 0x78, 0x3a, - 0xe7, 0xb9, 0x28, 0xc7, 0x0a, 0x83, 0x4a, 0x12, 0xcf, 0x0d, 0x83, 0x59, 0xdf, 0x89, 0xe5, 0xc3, - 0xac, 0x4a, 0x92, 0x2c, 0x48, 0x00, 0xd6, 0x38, 0xec, 0x3e, 0xdc, 0x8b, 0x5b, 0xbe, 0xb3, 0x63, - 0x9c, 0xca, 0x8d, 0x5c, 0x14, 0x0a, 0x84, 0x4d, 0x3c, 0xbb, 0x09, 0xe3, 0xe9, 0x8f, 0x98, 0x23, - 0x1b, 0xcc, 0x19, 0xb5, 0xa7, 0xe1, 0x9c, 0x82, 0x9a, 0xc3, 0x6a, 0x2d, 0xb6, 0x1d, 0xc1, 0x13, - 0xb4, 0x4b, 0xa6, 0x04, 0x60, 0x8d, 0x63, 0xff, 0x03, 0x0b, 0x4e, 0xe6, 0x0c, 0x5a, 0x81, 0x21, - 0x8e, 0x89, 0xe6, 0x36, 0x79, 0x3a, 0xc0, 0xdb, 0x61, 0xa0, 0x4e, 0x36, 0x1c, 0xe9, 0xee, 0x68, - 0x70, 0xcf, 0x39, 0x5e, 0x8c, 0x25, 0xdc, 0xfe, 0xed, 0x12, 0x8c, 0xa6, 0xfb, 0x1a, 0xb3, 0xb0, - 0x21, 0x3e, 0x4c, 0x5e, 0xec, 0x86, 0xdb, 0x24, 0xda, 0xa1, 0x5f, 0x6e, 0x65, 0xc2, 0x86, 0x3a, - 0x30, 0x70, 0x4e, 0x2d, 0x96, 0x41, 0xb8, 0xae, 0x46, 0x5b, 0xae, 0xc8, 0xeb, 0x45, 0xae, 0x48, - 0x3d, 0x99, 0xa6, 0x6b, 0x84, 0x22, 0x89, 0x4d, 0xfa, 0x54, 0x17, 0x61, 0x7e, 0xd8, 0x33, 0x6d, - 0xcf, 0x4f, 0xbc, 0x40, 0x7c, 0xb2, 0x58, 0xab, 0x4a, 0x17, 0x59, 0xea, 0x44, 0xc1, 0x79, 0xf5, - 0xec, 0xef, 0xf7, 0x81, 0x0a, 0xa9, 0x66, 0xae, 0x6b, 0x05, 0x39, 0xfe, 0x1d, 0x34, 0xf8, 0x4c, - 0xad, 0xad, 0xbe, 0xbd, 0x7c, 0x49, 0xb8, 0x29, 0xc7, 0xb4, 0xe7, 0xaa, 0x01, 0x5b, 0xd3, 0x20, - 0x6c, 0xe2, 0xd1, 0x9e, 0xf8, 0xde, 0x36, 0xe1, 0x95, 0xfa, 0xd3, 0x3d, 0x59, 0x94, 0x00, 0xac, - 0x71, 0x68, 0x4f, 0xea, 0xde, 0xc6, 0x86, 0xb0, 0x4b, 0xa8, 0x9e, 0xd0, 0xd1, 0xc1, 0x0c, 0xc2, - 0x73, 0xcc, 0x87, 0x5b, 0x42, 0xff, 0x36, 0x72, 0xcc, 0x87, 0x5b, 0x98, 0x41, 0xe8, 0x2c, 0x05, - 0x61, 0xd4, 0x74, 0x7c, 0xef, 0x35, 0x52, 0x57, 0x54, 0x84, 0xde, 0xad, 0x66, 0xe9, 0x6a, 0x27, - 0x0a, 0xce, 0xab, 0x47, 0x17, 0x74, 0x2b, 0x22, 0x75, 0xcf, 0x4d, 0xcc, 0xd6, 0x20, 0xbd, 0xa0, - 0x57, 0x3a, 0x30, 0x70, 0x4e, 0x2d, 0x34, 0x0d, 0xa3, 0x32, 0x24, 0x5e, 0x26, 0x3c, 0x1a, 0x4c, - 0x27, 0x58, 0xc1, 0x69, 0x30, 0xce, 0xe2, 0x53, 0x26, 0xd9, 0x14, 0x39, 0xd1, 0x98, 0x9a, 0x6e, - 0x30, 0x49, 0x99, 0x2b, 0x0d, 0x2b, 0x0c, 0xfb, 0x13, 0x65, 0x2a, 0xd4, 0xbb, 0xa4, 0x1e, 0x3c, - 0x36, 0x47, 0xd3, 0xf4, 0x8a, 0xec, 0xeb, 0x61, 0x45, 0x3e, 0x0b, 0x43, 0x37, 0xe3, 0x30, 0x50, - 0x4e, 0x9c, 0x95, 0xae, 0x4e, 0x9c, 0x06, 0x56, 0xbe, 0x13, 0x67, 0x7f, 0x51, 0x4e, 0x9c, 0x03, - 0xf7, 0xe8, 0xc4, 0xf9, 0x87, 0x15, 0x50, 0xef, 0xf5, 0x5c, 0x25, 0xc9, 0xad, 0x30, 0xda, 0xf2, - 0x82, 0x06, 0x4b, 0x25, 0xf0, 0x35, 0x0b, 0x86, 0xf8, 0x7e, 0x59, 0x34, 0x83, 0xf0, 0x36, 0x0a, - 0x7a, 0x08, 0x26, 0x45, 0x6c, 0x72, 0xcd, 0x20, 0x94, 0x79, 0xcb, 0xd7, 0x04, 0xe1, 0x54, 0x8f, - 0xd0, 0x47, 0x01, 0xa4, 0x11, 0x77, 0x43, 0x72, 0xe0, 0x85, 0x62, 0xfa, 0x87, 0xc9, 0x86, 0x56, - 0xa9, 0xd7, 0x14, 0x11, 0x6c, 0x10, 0x44, 0x9f, 0xd1, 0x01, 0x8a, 0x3c, 0xda, 0xe3, 0xc3, 0x47, - 0x32, 0x36, 0xbd, 0x84, 0x27, 0x62, 0x18, 0xf0, 0x82, 0x06, 0x5d, 0x27, 0xc2, 0xd9, 0xed, 0x6d, - 0x79, 0x69, 0x38, 0x16, 0x43, 0xa7, 0x3e, 0xe3, 0xf8, 0x4e, 0xe0, 0x92, 0x68, 0x81, 0xa3, 0x9b, - 0x8f, 0xeb, 0xb3, 0x02, 0x2c, 0x1b, 0xea, 0x78, 0xe9, 0xa8, 0xd2, 0xcb, 0x4b, 0x47, 0x67, 0xdf, - 0x07, 0x63, 0x1d, 0x93, 0x79, 0xa0, 0x68, 0xc4, 0x7b, 0x0f, 0x64, 0xb4, 0x7f, 0xa7, 0x5f, 0x0b, - 0xad, 0xab, 0x61, 0x9d, 0x3f, 0x9c, 0x13, 0xe9, 0x19, 0x15, 0x2a, 0x73, 0x81, 0x4b, 0xc4, 0x78, - 0xa0, 0x5f, 0x15, 0x62, 0x93, 0x24, 0x5d, 0xa3, 0x2d, 0x27, 0x22, 0xc1, 0x51, 0xaf, 0xd1, 0x15, - 0x45, 0x04, 0x1b, 0x04, 0xd1, 0x66, 0x2a, 0x1c, 0xe9, 0xe2, 0xe1, 0xc3, 0x91, 0x58, 0x82, 0xb2, - 0xbc, 0xf7, 0x25, 0xbe, 0x68, 0xc1, 0x48, 0x90, 0x5a, 0xb9, 0xc5, 0x78, 0x20, 0xe7, 0xef, 0x0a, - 0xfe, 0xdc, 0x5b, 0xba, 0x0c, 0x67, 0xe8, 0xe7, 0x89, 0xb4, 0xca, 0x01, 0x45, 0x9a, 0x7e, 0xb8, - 0xab, 0xbf, 0xdb, 0xc3, 0x5d, 0x28, 0x50, 0x2f, 0x17, 0x0e, 0x14, 0xfe, 0x72, 0x21, 0xe4, 0xbc, - 0x5a, 0x78, 0x03, 0x6a, 0x6e, 0x44, 0x9c, 0xe4, 0x1e, 0x1f, 0xb1, 0x63, 0xbe, 0x1d, 0xb3, 0xb2, - 0x01, 0xac, 0xdb, 0xb2, 0xff, 0x4f, 0x1f, 0x9c, 0x90, 0x23, 0x22, 0xa3, 0x17, 0xa8, 0x7c, 0xe4, - 0x74, 0xb5, 0xae, 0xac, 0xe4, 0xe3, 0x25, 0x09, 0xc0, 0x1a, 0x87, 0xea, 0x63, 0xed, 0x98, 0x2c, - 0xb7, 0x48, 0xb0, 0xe8, 0xad, 0xc7, 0xe2, 0x32, 0x56, 0x6d, 0x94, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, - 0xaa, 0xdb, 0x3b, 0x86, 0xd2, 0x6a, 0xe8, 0xf6, 0x52, 0x51, 0x95, 0x70, 0xf4, 0x2b, 0xb9, 0xb9, - 0x90, 0x8b, 0x89, 0xf9, 0xeb, 0x08, 0xda, 0x38, 0xe0, 0xbb, 0xa7, 0x7f, 0xd7, 0x82, 0xd3, 0xbc, - 0x54, 0x8e, 0xe4, 0xb5, 0x56, 0xdd, 0x49, 0x48, 0x5c, 0xcc, 0xdb, 0x04, 0x39, 0xfd, 0xd3, 0xe6, - 0xe5, 0x3c, 0xb2, 0x38, 0xbf, 0x37, 0xe8, 0x75, 0x0b, 0x46, 0xb7, 0x52, 0xe9, 0x62, 0xa4, 0xe8, - 0x38, 0x6c, 0x26, 0x87, 0x54, 0xa3, 0x7a, 0xab, 0xa5, 0xcb, 0x63, 0x9c, 0xa5, 0x6e, 0xff, 0x0f, - 0x0b, 0x4c, 0x36, 0x7a, 0xfc, 0x59, 0x66, 0x0e, 0xae, 0x0a, 0x4a, 0xed, 0xb2, 0xd2, 0x55, 0xbb, - 0x7c, 0x14, 0xca, 0x6d, 0xaf, 0x2e, 0xce, 0x17, 0xfa, 0x8a, 0x78, 0x61, 0x0e, 0xd3, 0x72, 0xfb, - 0x9f, 0x57, 0xb4, 0x19, 0x44, 0x84, 0xd4, 0xfd, 0x48, 0x7c, 0xf6, 0x86, 0xca, 0x53, 0xc7, 0xbf, - 0xfc, 0x6a, 0x47, 0x9e, 0xba, 0x9f, 0x3e, 0x78, 0xc4, 0x24, 0x1f, 0xa0, 0x6e, 0x69, 0xea, 0x06, - 0xf6, 0x09, 0x97, 0xbc, 0x09, 0x55, 0x7a, 0x04, 0x63, 0xf6, 0xcc, 0x6a, 0xaa, 0x53, 0xd5, 0x4b, - 0xa2, 0xfc, 0xee, 0xee, 0xc4, 0xbb, 0x0f, 0xde, 0x2d, 0x59, 0x1b, 0xab, 0xf6, 0x51, 0x0c, 0x35, - 0xfa, 0x9b, 0x45, 0x76, 0x8a, 0xc3, 0xdd, 0x35, 0xc5, 0x33, 0x25, 0xa0, 0x90, 0xb0, 0x51, 0x4d, - 0x07, 0x05, 0x50, 0x63, 0x4f, 0x44, 0x33, 0xa2, 0xfc, 0x0c, 0xb8, 0xa2, 0xe2, 0x2b, 0x25, 0xe0, - 0xee, 0xee, 0xc4, 0x0b, 0x07, 0x27, 0xaa, 0xaa, 0x63, 0x4d, 0xc2, 0xfe, 0x52, 0x9f, 0x5e, 0xbb, - 0x22, 0x3d, 0xe1, 0x8f, 0xc4, 0xda, 0x7d, 0x3e, 0xb3, 0x76, 0xcf, 0x75, 0xac, 0xdd, 0x11, 0xfd, - 0x94, 0x71, 0x6a, 0x35, 0x1e, 0xb7, 0x22, 0xb0, 0xbf, 0xbd, 0x81, 0x69, 0x40, 0xaf, 0xb6, 0xbd, - 0x88, 0xc4, 0x2b, 0x51, 0x3b, 0xf0, 0x82, 0x06, 0x5b, 0x8e, 0x55, 0x53, 0x03, 0x4a, 0x81, 0x71, - 0x16, 0x9f, 0x1e, 0xea, 0xe9, 0x9c, 0xdf, 0x70, 0xb6, 0xf9, 0xaa, 0x32, 0x32, 0xb6, 0xad, 0x8a, - 0x72, 0xac, 0x30, 0xec, 0x6f, 0xb0, 0x5b, 0x74, 0x23, 0xa4, 0x9c, 0xae, 0x09, 0x9f, 0xbd, 0xc9, - 0xcd, 0xd3, 0xbd, 0xa9, 0x35, 0xc1, 0x1f, 0xe2, 0xe6, 0x30, 0x74, 0x0b, 0x06, 0xd6, 0xf9, 0xeb, - 0x92, 0xc5, 0x64, 0xdc, 0x17, 0x4f, 0x55, 0xb2, 0x77, 0x7b, 0xe4, 0xbb, 0x95, 0x77, 0xf5, 0x4f, - 0x2c, 0xa9, 0xd9, 0xdf, 0xae, 0xc0, 0x68, 0xe6, 0xd5, 0xe6, 0x54, 0xa2, 0xdd, 0xd2, 0xbe, 0x89, - 0x76, 0x3f, 0x04, 0x50, 0x27, 0x2d, 0x3f, 0xdc, 0x61, 0xea, 0x58, 0xdf, 0x81, 0xd5, 0x31, 0xa5, - 0xc1, 0xcf, 0xa9, 0x56, 0xb0, 0xd1, 0xa2, 0xc8, 0x71, 0xc7, 0xf3, 0xf6, 0x66, 0x72, 0xdc, 0x19, - 0xef, 0x72, 0xf4, 0x1f, 0xef, 0xbb, 0x1c, 0x1e, 0x8c, 0xf2, 0x2e, 0xaa, 0xc0, 0xed, 0x7b, 0x88, - 0xcf, 0x66, 0xa1, 0x2f, 0x73, 0xe9, 0x66, 0x70, 0xb6, 0xdd, 0xfb, 0xf9, 0x28, 0x3b, 0x7a, 0x07, - 0xd4, 0xe4, 0x3c, 0xc7, 0xe3, 0x35, 0x9d, 0xfc, 0x42, 0x2e, 0x03, 0xf6, 0x58, 0xba, 0xf8, 0xd9, - 0x91, 0x83, 0x02, 0xee, 0x57, 0x0e, 0x0a, 0xfb, 0x0b, 0x25, 0xaa, 0xc7, 0xf3, 0x7e, 0xa9, 0x74, - 0x4a, 0x4f, 0x40, 0xbf, 0xd3, 0x4e, 0x36, 0xc3, 0x8e, 0xf7, 0x29, 0xa7, 0x59, 0x29, 0x16, 0x50, - 0xb4, 0x08, 0x7d, 0x75, 0x9d, 0x22, 0xe7, 0x20, 0xf3, 0xa9, 0x4d, 0xa2, 0x4e, 0x42, 0x30, 0x6b, - 0x05, 0x3d, 0x02, 0x7d, 0x89, 0xd3, 0x90, 0xd1, 0x7a, 0x2c, 0x42, 0x7b, 0xcd, 0x69, 0xc4, 0x98, - 0x95, 0x9a, 0xe2, 0xbb, 0x6f, 0x1f, 0xf1, 0xfd, 0x02, 0x0c, 0xc7, 0x5e, 0x23, 0x70, 0x92, 0x76, - 0x44, 0x8c, 0x5b, 0x43, 0xed, 0x33, 0x62, 0x02, 0x71, 0x1a, 0xd7, 0xfe, 0xdd, 0x21, 0x38, 0xb5, - 0x3a, 0xbb, 0x24, 0x13, 0xbf, 0x1f, 0x59, 0xc0, 0x5d, 0x1e, 0x8d, 0xe3, 0x0b, 0xb8, 0xeb, 0x42, - 0xdd, 0x37, 0x02, 0xee, 0x7c, 0x23, 0xe0, 0x2e, 0x1d, 0xfd, 0x54, 0x2e, 0x22, 0xfa, 0x29, 0xaf, - 0x07, 0xbd, 0x44, 0x3f, 0x1d, 0x59, 0x04, 0xde, 0x9e, 0x1d, 0x3a, 0x50, 0x04, 0x9e, 0x0a, 0x4f, - 0x2c, 0x24, 0x2e, 0xa5, 0xcb, 0x54, 0xe5, 0x86, 0x27, 0xaa, 0xd0, 0x30, 0x1e, 0x73, 0x25, 0x58, - 0xfd, 0xcb, 0xc5, 0x77, 0xa0, 0x87, 0xd0, 0x30, 0x11, 0xf6, 0x65, 0x86, 0x23, 0x0e, 0x14, 0x11, - 0x8e, 0x98, 0xd7, 0x9d, 0x7d, 0xc3, 0x11, 0x5f, 0x80, 0x61, 0xd7, 0x0f, 0x03, 0xb2, 0x12, 0x85, - 0x49, 0xe8, 0x86, 0xbe, 0x50, 0xeb, 0xf5, 0x43, 0x34, 0x26, 0x10, 0xa7, 0x71, 0xbb, 0xc5, 0x32, - 0xd6, 0x0e, 0x1b, 0xcb, 0x08, 0xf7, 0x29, 0x96, 0xf1, 0x17, 0x75, 0xd4, 0xfd, 0x20, 0x9b, 0x91, - 0x0f, 0x15, 0x3f, 0x23, 0xbd, 0x84, 0xde, 0xa3, 0x37, 0xf8, 0x03, 0x91, 0x54, 0x31, 0x9e, 0x0d, - 0x9b, 0x54, 0xf1, 0x1b, 0x62, 0x43, 0xf2, 0xca, 0x11, 0x2c, 0xd8, 0x1b, 0xab, 0x9a, 0x8c, 0x7a, - 0x34, 0x52, 0x17, 0xe1, 0x74, 0x47, 0x0e, 0x93, 0x15, 0xe0, 0x2b, 0x25, 0xf8, 0xb1, 0x7d, 0xbb, - 0x80, 0x6e, 0x01, 0x24, 0x4e, 0x43, 0x2c, 0x54, 0x71, 0x61, 0x72, 0x48, 0xc7, 0xce, 0x35, 0xd9, - 0x1e, 0x4f, 0x67, 0xa3, 0xfe, 0xb2, 0xab, 0x08, 0xf9, 0x9b, 0xf9, 0x73, 0x86, 0x7e, 0x47, 0xd6, - 0x4f, 0x1c, 0xfa, 0x04, 0x33, 0x08, 0x15, 0xff, 0x11, 0x69, 0xe8, 0xd7, 0xd5, 0xd5, 0xf4, 0x61, - 0x56, 0x8a, 0x05, 0x14, 0x3d, 0x07, 0x83, 0x8e, 0xef, 0xf3, 0xa0, 0x21, 0x12, 0x8b, 0x17, 0xa2, - 0x74, 0xfa, 0x41, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0x17, 0x25, 0x98, 0xd8, 0x87, 0xa7, 0x74, 0x04, - 0x8b, 0x56, 0x7a, 0x0e, 0x16, 0x15, 0x81, 0x14, 0xfd, 0x5d, 0x02, 0x29, 0x9e, 0x83, 0xc1, 0x84, - 0x38, 0x4d, 0xe1, 0x0a, 0x26, 0x2c, 0x01, 0xfa, 0x06, 0x58, 0x83, 0xb0, 0x89, 0x47, 0xb9, 0xd8, - 0x88, 0xe3, 0xba, 0x24, 0x8e, 0x65, 0xa4, 0x84, 0xb0, 0xa6, 0x16, 0x16, 0x86, 0xc1, 0x8c, 0xd4, - 0xd3, 0x29, 0x12, 0x38, 0x43, 0x32, 0x3b, 0xe0, 0xb5, 0x1e, 0x07, 0xfc, 0xeb, 0x25, 0x78, 0x74, - 0x4f, 0xe9, 0xd6, 0x73, 0x10, 0x4b, 0x3b, 0x26, 0x51, 0x76, 0xe1, 0x5c, 0x8b, 0x49, 0x84, 0x19, - 0x84, 0x8f, 0x52, 0xab, 0x65, 0xbc, 0x5e, 0x5f, 0x74, 0x44, 0x17, 0x1f, 0xa5, 0x14, 0x09, 0x9c, - 0x21, 0x79, 0xaf, 0xcb, 0xf2, 0xdb, 0x7d, 0xf0, 0x78, 0x0f, 0x3a, 0x40, 0x81, 0x91, 0x6f, 0xe9, - 0x28, 0xcd, 0xf2, 0x7d, 0x8a, 0xd2, 0xbc, 0xb7, 0xe1, 0x7a, 0x33, 0xb8, 0xb3, 0xa7, 0x08, 0xbb, - 0x6f, 0x94, 0xe0, 0x6c, 0x77, 0x85, 0x05, 0xbd, 0x07, 0x46, 0x23, 0xe5, 0xfa, 0x66, 0x06, 0x78, - 0x9e, 0xe4, 0xf6, 0x96, 0x14, 0x08, 0x67, 0x71, 0xd1, 0x24, 0x40, 0xcb, 0x49, 0x36, 0xe3, 0x0b, - 0xb7, 0xbd, 0x38, 0x11, 0x69, 0x9e, 0x46, 0xf8, 0x0d, 0x9f, 0x2c, 0xc5, 0x06, 0x06, 0x25, 0xc7, - 0xfe, 0xcd, 0x85, 0x57, 0xc3, 0x84, 0x57, 0xe2, 0x87, 0xad, 0x93, 0xf2, 0x51, 0x1c, 0x03, 0x84, - 0xb3, 0xb8, 0x94, 0x1c, 0xbb, 0x43, 0xe6, 0x1d, 0xe5, 0xa7, 0x30, 0x46, 0x6e, 0x51, 0x95, 0x62, - 0x03, 0x23, 0x1b, 0xba, 0x5a, 0xd9, 0x3f, 0x74, 0xd5, 0xfe, 0x67, 0x25, 0x38, 0xd3, 0x55, 0xe1, - 0xed, 0x8d, 0x4d, 0x3d, 0x78, 0xe1, 0xa6, 0xf7, 0xb8, 0xc3, 0x0e, 0x16, 0xa6, 0xf8, 0xa7, 0x5d, - 0x56, 0x9a, 0x08, 0x53, 0xbc, 0xf7, 0xec, 0x0b, 0x0f, 0xde, 0x78, 0x76, 0x44, 0x26, 0xf6, 0x1d, - 0x20, 0x32, 0x31, 0x33, 0x19, 0x95, 0x1e, 0xa5, 0xc3, 0x9f, 0xf7, 0x75, 0x1d, 0x5e, 0x7a, 0x40, - 0xee, 0xc9, 0x9a, 0x3d, 0x07, 0x27, 0xbc, 0x80, 0x3d, 0x90, 0xb6, 0xda, 0x5e, 0x17, 0x99, 0x7f, - 0x78, 0x7a, 0x4b, 0x15, 0xfe, 0xb0, 0x90, 0x81, 0xe3, 0x8e, 0x1a, 0x0f, 0x60, 0xa4, 0xe8, 0xbd, - 0x0d, 0xe9, 0x01, 0x39, 0xf7, 0x32, 0x9c, 0x96, 0x43, 0xb1, 0xe9, 0x44, 0xa4, 0x2e, 0x84, 0x6d, - 0x2c, 0x02, 0x5e, 0xce, 0xf0, 0xa0, 0x99, 0x1c, 0x04, 0x9c, 0x5f, 0x8f, 0xbd, 0x49, 0x15, 0xb6, - 0x3c, 0x57, 0x1c, 0x05, 0xf5, 0x9b, 0x54, 0xb4, 0x10, 0x73, 0x98, 0x96, 0x17, 0xb5, 0xe3, 0x91, - 0x17, 0x1f, 0x82, 0x9a, 0x1a, 0x6f, 0xee, 0xbb, 0xaf, 0x16, 0x79, 0x87, 0xef, 0xbe, 0x5a, 0xe1, - 0x06, 0xd6, 0x7e, 0x8f, 0xa6, 0xbe, 0x13, 0x86, 0x94, 0xf5, 0xab, 0xd7, 0x97, 0xc1, 0xec, 0x2f, - 0xf5, 0xc3, 0x70, 0x2a, 0xdb, 0x67, 0xca, 0xec, 0x6d, 0xed, 0x6b, 0xf6, 0x66, 0x61, 0x1b, 0xed, - 0x40, 0x3e, 0x1b, 0x68, 0x84, 0x6d, 0xb4, 0x03, 0x82, 0x39, 0x8c, 0x1e, 0x3a, 0xea, 0xd1, 0x0e, - 0x6e, 0x07, 0xc2, 0x0f, 0x55, 0x1d, 0x3a, 0xe6, 0x58, 0x29, 0x16, 0x50, 0xf4, 0x71, 0x0b, 0x86, - 0x62, 0x76, 0xa7, 0xc2, 0x2f, 0x0d, 0xc4, 0x22, 0xbf, 0x7c, 0xf8, 0x64, 0xa6, 0x2a, 0xb3, 0x2d, - 0xf3, 0x5b, 0x32, 0x4b, 0x70, 0x8a, 0x22, 0xfa, 0x94, 0x05, 0x35, 0xf5, 0xba, 0x91, 0x78, 0x03, - 0x74, 0xb5, 0xd8, 0x64, 0xaa, 0xdc, 0xda, 0xac, 0xae, 0xa7, 0x54, 0x56, 0x4b, 0xac, 0x09, 0xa3, - 0x58, 0x59, 0xf4, 0x07, 0x8e, 0xc6, 0xa2, 0x0f, 0x39, 0xd6, 0xfc, 0x77, 0x40, 0xad, 0xe9, 0x04, - 0xde, 0x06, 0x89, 0x13, 0x6e, 0x64, 0x97, 0x39, 0x9e, 0x65, 0x21, 0xd6, 0x70, 0xaa, 0x00, 0xc4, - 0xec, 0xc3, 0x12, 0xc3, 0x2a, 0xce, 0x14, 0x80, 0x55, 0x5d, 0x8c, 0x4d, 0x1c, 0xd3, 0x84, 0x0f, - 0xf7, 0xd5, 0x84, 0x3f, 0xb8, 0xb7, 0x09, 0xdf, 0xfe, 0xc7, 0x16, 0x9c, 0xce, 0x9d, 0xb5, 0x07, - 0xd7, 0x1d, 0xd5, 0xfe, 0x72, 0x05, 0x4e, 0xe6, 0xa4, 0xed, 0x45, 0x3b, 0xe6, 0x7a, 0xb6, 0x8a, - 0xf0, 0xec, 0x48, 0x3b, 0x2a, 0xc8, 0x61, 0xcc, 0x59, 0xc4, 0x07, 0xbb, 0x40, 0xd3, 0x97, 0x58, - 0xe5, 0xe3, 0xbd, 0xc4, 0x32, 0x96, 0x65, 0xdf, 0x7d, 0x5d, 0x96, 0x95, 0x7d, 0x6e, 0x96, 0xbe, - 0x69, 0xc1, 0x78, 0xb3, 0xcb, 0x5b, 0x11, 0xc2, 0x1c, 0x7c, 0xfd, 0x68, 0x5e, 0xa2, 0x98, 0x79, - 0xe4, 0xce, 0xee, 0x44, 0xd7, 0x27, 0x3a, 0x70, 0xd7, 0x5e, 0xd9, 0xdf, 0x2f, 0x03, 0xcb, 0x19, - 0xcd, 0x52, 0x33, 0xee, 0xa0, 0x8f, 0x99, 0xd9, 0xbf, 0xad, 0xa2, 0x32, 0x55, 0xf3, 0xc6, 0x55, - 0xf6, 0x70, 0x3e, 0x82, 0x79, 0xc9, 0xc4, 0xb3, 0x4c, 0xab, 0xd4, 0x03, 0xd3, 0xf2, 0x65, 0x9a, - 0xf5, 0x72, 0xf1, 0x69, 0xd6, 0x6b, 0xd9, 0x14, 0xeb, 0x7b, 0x4f, 0x71, 0xdf, 0x03, 0x39, 0xc5, - 0xbf, 0x6a, 0x71, 0xc6, 0x93, 0x99, 0x05, 0xad, 0x19, 0x58, 0x7b, 0x68, 0x06, 0x4f, 0x41, 0x35, - 0x26, 0xfe, 0xc6, 0x25, 0xe2, 0xf8, 0x42, 0x83, 0xd0, 0x5e, 0x05, 0xa2, 0x1c, 0x2b, 0x0c, 0xf6, - 0x0e, 0xb3, 0xef, 0x87, 0xb7, 0x2e, 0x34, 0x5b, 0xc9, 0x8e, 0xd0, 0x25, 0xf4, 0x3b, 0xcc, 0x0a, - 0x82, 0x0d, 0x2c, 0xfb, 0xef, 0x94, 0xf8, 0x0a, 0x14, 0xae, 0x29, 0xcf, 0x67, 0x5e, 0xce, 0xec, - 0xdd, 0xab, 0xe3, 0x23, 0x00, 0x6e, 0xd8, 0x6c, 0x51, 0x3d, 0x73, 0x2d, 0x14, 0x37, 0x75, 0x97, - 0x0e, 0xfd, 0x4e, 0xbf, 0x68, 0x4f, 0x7f, 0x86, 0x2e, 0xc3, 0x06, 0xbd, 0x14, 0x2f, 0x2d, 0xef, - 0xcb, 0x4b, 0x53, 0x6c, 0xa5, 0x6f, 0x1f, 0x69, 0xf7, 0x17, 0x16, 0xa4, 0x34, 0x22, 0xd4, 0x82, - 0x0a, 0xed, 0xee, 0x8e, 0xd8, 0xa1, 0xcb, 0xc5, 0xa9, 0x5f, 0x94, 0x35, 0x8a, 0x65, 0xcf, 0x7e, - 0x62, 0x4e, 0x08, 0xf9, 0xc2, 0x83, 0x85, 0x8f, 0xea, 0xd5, 0xe2, 0x08, 0x5e, 0x0a, 0xc3, 0x2d, - 0x7e, 0xdd, 0xac, 0xbd, 0x61, 0xec, 0xe7, 0x61, 0xac, 0xa3, 0x53, 0xec, 0x91, 0xbc, 0x90, 0x4a, - 0x9f, 0xcc, 0x72, 0x65, 0x01, 0xbd, 0x98, 0xc3, 0xec, 0x6f, 0x58, 0x70, 0x22, 0xdb, 0x3c, 0x7a, - 0xc3, 0x82, 0xb1, 0x38, 0xdb, 0xde, 0x51, 0x8d, 0x9d, 0xf2, 0x42, 0xed, 0x00, 0xe1, 0xce, 0x4e, - 0xd8, 0xff, 0x57, 0x2c, 0xfe, 0x1b, 0x5e, 0x50, 0x0f, 0x6f, 0x29, 0xc5, 0xc4, 0xea, 0xaa, 0x98, - 0xd0, 0xfd, 0xe8, 0x6e, 0x92, 0x7a, 0xdb, 0xef, 0x08, 0x0f, 0x5e, 0x15, 0xe5, 0x58, 0x61, 0xb0, - 0x68, 0xc8, 0xb6, 0x78, 0x87, 0x21, 0xb3, 0x28, 0xe7, 0x44, 0x39, 0x56, 0x18, 0xe8, 0x59, 0x18, - 0x32, 0x3e, 0x52, 0xae, 0x4b, 0xa6, 0x90, 0x1b, 0x22, 0x33, 0xc6, 0x29, 0x2c, 0x34, 0x09, 0xa0, - 0x94, 0x1c, 0x29, 0x22, 0x99, 0x61, 0x4a, 0x71, 0xa2, 0x18, 0x1b, 0x18, 0x2c, 0xf6, 0xd8, 0x6f, - 0xc7, 0xec, 0xe6, 0xa5, 0x5f, 0xe7, 0x06, 0x9e, 0x15, 0x65, 0x58, 0x41, 0x29, 0x37, 0x69, 0x3a, - 0x41, 0xdb, 0xf1, 0xe9, 0x08, 0x89, 0xa3, 0xa6, 0xda, 0x86, 0x4b, 0x0a, 0x82, 0x0d, 0x2c, 0xfa, - 0xc5, 0x89, 0xd7, 0x24, 0x2f, 0x85, 0x81, 0xf4, 0x1e, 0xd4, 0x97, 0x71, 0xa2, 0x1c, 0x2b, 0x0c, - 0xfb, 0xbf, 0x59, 0x30, 0xaa, 0x93, 0x1e, 0xf0, 0xe7, 0xf0, 0xcd, 0x93, 0xb1, 0xb5, 0xef, 0xc9, - 0x38, 0x1d, 0xe2, 0x5d, 0xea, 0x29, 0xc4, 0xdb, 0x8c, 0xbe, 0x2e, 0xef, 0x19, 0x7d, 0xfd, 0x13, - 0xfa, 0xa9, 0x65, 0x1e, 0xa6, 0x3d, 0x98, 0xf7, 0xcc, 0x32, 0xb2, 0xa1, 0xdf, 0x75, 0x54, 0x72, - 0xa0, 0x21, 0x7e, 0x76, 0x98, 0x9d, 0x66, 0x48, 0x02, 0x62, 0x2f, 0x43, 0x4d, 0xdd, 0x49, 0xc9, - 0x83, 0xaa, 0x95, 0x7f, 0x50, 0xed, 0x29, 0x0a, 0x74, 0x66, 0xfd, 0x5b, 0x3f, 0x78, 0xec, 0x2d, - 0x7f, 0xfc, 0x83, 0xc7, 0xde, 0xf2, 0xbd, 0x1f, 0x3c, 0xf6, 0x96, 0x8f, 0xdf, 0x79, 0xcc, 0xfa, - 0xd6, 0x9d, 0xc7, 0xac, 0x3f, 0xbe, 0xf3, 0x98, 0xf5, 0xbd, 0x3b, 0x8f, 0x59, 0xdf, 0xbf, 0xf3, - 0x98, 0xf5, 0xc5, 0xff, 0xfc, 0xd8, 0x5b, 0x5e, 0xca, 0x75, 0x1f, 0xa5, 0x3f, 0x9e, 0x76, 0xeb, - 0x53, 0xdb, 0xe7, 0x99, 0x07, 0x23, 0xdd, 0x5e, 0x53, 0xc6, 0x9a, 0x9a, 0x92, 0xdb, 0xeb, 0xff, - 0x05, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x7b, 0xca, 0xa6, 0xc3, 0xea, 0x00, 0x00, + // 11861 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, + 0x75, 0x18, 0xae, 0xd9, 0xc5, 0x02, 0xbb, 0x0f, 0x5f, 0x64, 0x93, 0xbc, 0xc3, 0xf1, 0x3e, 0x40, + 0xcf, 0xc9, 0xa7, 0xf3, 0x4f, 0x77, 0x80, 0x8f, 0xbe, 0x93, 0xef, 0xe7, 0xb3, 0x24, 0xe3, 0x83, + 0x04, 0x41, 0x02, 0x04, 0xae, 0x17, 0x24, 0xa5, 0x93, 0x4f, 0xa7, 0xc1, 0x6e, 0x63, 0x31, 0xc4, + 0xec, 0xcc, 0xde, 0xcc, 0x2c, 0x88, 0x3d, 0x4b, 0xb2, 0x64, 0x49, 0xb6, 0x6c, 0x7d, 0x46, 0x4a, + 0xc5, 0xe7, 0xc4, 0x52, 0x64, 0x4b, 0x49, 0x25, 0x95, 0x52, 0x59, 0x89, 0xff, 0x88, 0x53, 0xb6, + 0xcb, 0x15, 0x3b, 0xe5, 0x52, 0xe2, 0xa4, 0xec, 0xa8, 0x54, 0x96, 0x12, 0xdb, 0x88, 0xc4, 0x38, + 0x65, 0x57, 0xfe, 0x70, 0x55, 0x9c, 0xfc, 0x91, 0x62, 0x5c, 0xa9, 0x54, 0x7f, 0xf7, 0xcc, 0xce, + 0x02, 0x0b, 0x62, 0x00, 0x52, 0xf2, 0xfd, 0xb7, 0xdb, 0xef, 0xcd, 0x7b, 0x3d, 0x3d, 0xdd, 0xef, + 0xbd, 0x7e, 0xfd, 0xde, 0x6b, 0x58, 0x6a, 0xb8, 0xf1, 0x66, 0x7b, 0x7d, 0xaa, 0x16, 0x34, 0xa7, + 0x9d, 0xb0, 0x11, 0xb4, 0xc2, 0xe0, 0x26, 0xfb, 0xf1, 0x74, 0xad, 0x3e, 0xbd, 0x7d, 0x7e, 0xba, + 0xb5, 0xd5, 0x98, 0x76, 0x5a, 0x6e, 0x34, 0xed, 0xb4, 0x5a, 0x9e, 0x5b, 0x73, 0x62, 0x37, 0xf0, + 0xa7, 0xb7, 0x9f, 0x71, 0xbc, 0xd6, 0xa6, 0xf3, 0xcc, 0x74, 0x83, 0xf8, 0x24, 0x74, 0x62, 0x52, + 0x9f, 0x6a, 0x85, 0x41, 0x1c, 0xa0, 0x1f, 0xd7, 0xd4, 0xa6, 0x24, 0x35, 0xf6, 0xe3, 0x95, 0x5a, + 0x7d, 0x6a, 0xfb, 0xfc, 0x54, 0x6b, 0xab, 0x31, 0x45, 0xa9, 0x4d, 0x19, 0xd4, 0xa6, 0x24, 0xb5, + 0xb3, 0x4f, 0x1b, 0x7d, 0x69, 0x04, 0x8d, 0x60, 0x9a, 0x11, 0x5d, 0x6f, 0x6f, 0xb0, 0x7f, 0xec, + 0x0f, 0xfb, 0xc5, 0x99, 0x9d, 0xb5, 0xb7, 0x9e, 0x8f, 0xa6, 0xdc, 0x80, 0x76, 0x6f, 0xba, 0x16, + 0x84, 0x64, 0x7a, 0xbb, 0xab, 0x43, 0x67, 0x2f, 0x69, 0x1c, 0xb2, 0x13, 0x13, 0x3f, 0x72, 0x03, + 0x3f, 0x7a, 0x9a, 0x76, 0x81, 0x84, 0xdb, 0x24, 0x34, 0x5f, 0xcf, 0x40, 0xc8, 0xa2, 0xf4, 0xac, + 0xa6, 0xd4, 0x74, 0x6a, 0x9b, 0xae, 0x4f, 0xc2, 0x8e, 0x7e, 0xbc, 0x49, 0x62, 0x27, 0xeb, 0xa9, + 0xe9, 0x5e, 0x4f, 0x85, 0x6d, 0x3f, 0x76, 0x9b, 0xa4, 0xeb, 0x81, 0xb7, 0xed, 0xf7, 0x40, 0x54, + 0xdb, 0x24, 0x4d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x3b, 0x76, 0xbd, 0x69, 0xd7, 0x8f, + 0xa3, 0x38, 0x4c, 0x3f, 0x64, 0xff, 0xb2, 0x05, 0xa3, 0x33, 0x37, 0xaa, 0x33, 0xed, 0x78, 0x73, + 0x2e, 0xf0, 0x37, 0xdc, 0x06, 0x7a, 0x0e, 0x86, 0x6b, 0x5e, 0x3b, 0x8a, 0x49, 0x78, 0xd5, 0x69, + 0x92, 0x09, 0xeb, 0x9c, 0xf5, 0x64, 0x65, 0xf6, 0xd4, 0xd7, 0x77, 0x27, 0xdf, 0x74, 0x7b, 0x77, + 0x72, 0x78, 0x4e, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x86, 0xc2, 0xc0, 0x23, 0x33, 0xf8, 0xea, + 0x44, 0x81, 0x3d, 0x32, 0x2e, 0x1e, 0x19, 0xc2, 0xbc, 0x19, 0x4b, 0x38, 0x45, 0x6d, 0x85, 0xc1, + 0x86, 0xeb, 0x91, 0x89, 0x62, 0x12, 0x75, 0x95, 0x37, 0x63, 0x09, 0xb7, 0xff, 0xb8, 0x00, 0x30, + 0xd3, 0x6a, 0xad, 0x86, 0xc1, 0x4d, 0x52, 0x8b, 0xd1, 0xfb, 0xa0, 0x4c, 0x87, 0xb9, 0xee, 0xc4, + 0x0e, 0xeb, 0xd8, 0xf0, 0xf9, 0x1f, 0x9e, 0xe2, 0x6f, 0x3d, 0x65, 0xbe, 0xb5, 0x9e, 0x64, 0x14, + 0x7b, 0x6a, 0xfb, 0x99, 0xa9, 0x95, 0x75, 0xfa, 0xfc, 0x32, 0x89, 0x9d, 0x59, 0x24, 0x98, 0x81, + 0x6e, 0xc3, 0x8a, 0x2a, 0xf2, 0x61, 0x20, 0x6a, 0x91, 0x1a, 0x7b, 0x87, 0xe1, 0xf3, 0x4b, 0x53, + 0x87, 0x99, 0xcd, 0x53, 0xba, 0xe7, 0xd5, 0x16, 0xa9, 0xcd, 0x8e, 0x08, 0xce, 0x03, 0xf4, 0x1f, + 0x66, 0x7c, 0xd0, 0x36, 0x0c, 0x46, 0xb1, 0x13, 0xb7, 0x23, 0x36, 0x14, 0xc3, 0xe7, 0xaf, 0xe6, + 0xc6, 0x91, 0x51, 0x9d, 0x1d, 0x13, 0x3c, 0x07, 0xf9, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x66, 0xc1, + 0x98, 0x46, 0x5e, 0x72, 0xa3, 0x18, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf5, 0x37, 0xb8, 0xf4, 0x69, + 0x36, 0xb4, 0x27, 0x04, 0xb3, 0xb2, 0x6c, 0x31, 0x06, 0xb6, 0x09, 0x25, 0x37, 0x26, 0xcd, 0x68, + 0xa2, 0x70, 0xae, 0xf8, 0xe4, 0xf0, 0xf9, 0x4b, 0x79, 0xbd, 0xe7, 0xec, 0xa8, 0x60, 0x5a, 0x5a, + 0xa4, 0xe4, 0x31, 0xe7, 0x62, 0xff, 0xf5, 0xa8, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x33, 0x30, 0x1c, + 0x05, 0xed, 0xb0, 0x46, 0x30, 0x69, 0x05, 0xd1, 0x84, 0x75, 0xae, 0x48, 0xa7, 0x1e, 0x9d, 0xd4, + 0x55, 0xdd, 0x8c, 0x4d, 0x1c, 0xf4, 0x69, 0x0b, 0x46, 0xea, 0x24, 0x8a, 0x5d, 0x9f, 0xf1, 0x97, + 0x9d, 0x5f, 0x3b, 0x74, 0xe7, 0x65, 0xe3, 0xbc, 0x26, 0x3e, 0x7b, 0x5a, 0xbc, 0xc8, 0x88, 0xd1, + 0x18, 0xe1, 0x04, 0x7f, 0xba, 0x38, 0xeb, 0x24, 0xaa, 0x85, 0x6e, 0x8b, 0xfe, 0x17, 0xcb, 0x47, + 0x2d, 0xce, 0x79, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x44, 0x17, 0x5f, 0x34, 0x31, 0xc0, 0xfa, + 0xbf, 0x78, 0xb8, 0xfe, 0x8b, 0x41, 0xa5, 0xeb, 0x5a, 0x8f, 0x3e, 0xfd, 0x17, 0x61, 0xce, 0x06, + 0x7d, 0xca, 0x82, 0x09, 0x21, 0x1c, 0x30, 0xe1, 0x03, 0x7a, 0x63, 0xd3, 0x8d, 0x89, 0xe7, 0x46, + 0xf1, 0x44, 0x89, 0xf5, 0x61, 0xba, 0xbf, 0xb9, 0xb5, 0x10, 0x06, 0xed, 0xd6, 0x15, 0xd7, 0xaf, + 0xcf, 0x9e, 0x13, 0x9c, 0x26, 0xe6, 0x7a, 0x10, 0xc6, 0x3d, 0x59, 0xa2, 0xcf, 0x5b, 0x70, 0xd6, + 0x77, 0x9a, 0x24, 0x6a, 0x39, 0xf4, 0xd3, 0x72, 0xf0, 0xac, 0xe7, 0xd4, 0xb6, 0x58, 0x8f, 0x06, + 0xef, 0xae, 0x47, 0xb6, 0xe8, 0xd1, 0xd9, 0xab, 0x3d, 0x49, 0xe3, 0x3d, 0xd8, 0xa2, 0x2f, 0x5b, + 0x70, 0x32, 0x08, 0x5b, 0x9b, 0x8e, 0x4f, 0xea, 0x12, 0x1a, 0x4d, 0x0c, 0xb1, 0xa5, 0xf7, 0xde, + 0xc3, 0x7d, 0xa2, 0x95, 0x34, 0xd9, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, + 0x46, 0x34, 0x7b, 0xe6, 0xf6, 0xee, 0xe4, 0xc9, 0x2e, 0x2c, 0xdc, 0xdd, 0x1f, 0xf4, 0x53, 0x30, + 0x1c, 0x75, 0xfc, 0xda, 0x0d, 0xd7, 0xaf, 0x07, 0xb7, 0xa2, 0x89, 0x72, 0x1e, 0xcb, 0xb7, 0xaa, + 0x08, 0x8a, 0x05, 0xa8, 0x19, 0x60, 0x93, 0x5b, 0xf6, 0x87, 0xd3, 0x53, 0xa9, 0x92, 0xf7, 0x87, + 0xd3, 0x93, 0x69, 0x0f, 0xb6, 0xe8, 0xe7, 0x2c, 0x18, 0x8d, 0xdc, 0x86, 0xef, 0xc4, 0xed, 0x90, + 0x5c, 0x21, 0x9d, 0x68, 0x02, 0x58, 0x47, 0x2e, 0x1f, 0x72, 0x54, 0x0c, 0x92, 0xb3, 0x67, 0x44, + 0x1f, 0x47, 0xcd, 0xd6, 0x08, 0x27, 0xf9, 0x66, 0x2d, 0x34, 0x3d, 0xad, 0x87, 0xf3, 0x5d, 0x68, + 0x7a, 0x52, 0xf7, 0x64, 0x89, 0x7e, 0x02, 0x4e, 0xf0, 0x26, 0x35, 0xb2, 0xd1, 0xc4, 0x08, 0x13, + 0xb4, 0xa7, 0x6f, 0xef, 0x4e, 0x9e, 0xa8, 0xa6, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0a, 0x93, 0x2d, + 0x12, 0x36, 0xdd, 0x78, 0xc5, 0xf7, 0x3a, 0x52, 0x7c, 0xd7, 0x82, 0x16, 0xa9, 0x8b, 0xee, 0x44, + 0x13, 0xa3, 0xe7, 0xac, 0x27, 0xcb, 0xb3, 0x6f, 0x11, 0xdd, 0x9c, 0x5c, 0xdd, 0x1b, 0x1d, 0xef, + 0x47, 0x0f, 0xfd, 0xbe, 0x05, 0x67, 0x0d, 0x29, 0x5b, 0x25, 0xe1, 0xb6, 0x5b, 0x23, 0x33, 0xb5, + 0x5a, 0xd0, 0xf6, 0xe3, 0x68, 0x62, 0x8c, 0x0d, 0xe3, 0xfa, 0x51, 0xc8, 0xfc, 0x24, 0x2b, 0x3d, + 0x2f, 0x7b, 0xa2, 0x44, 0x78, 0x8f, 0x9e, 0xda, 0xff, 0xb6, 0x00, 0x27, 0xd2, 0x16, 0x00, 0xfa, + 0xc7, 0x16, 0x8c, 0xdf, 0xbc, 0x15, 0xaf, 0x05, 0x5b, 0xc4, 0x8f, 0x66, 0x3b, 0x54, 0x4e, 0x33, + 0xdd, 0x37, 0x7c, 0xbe, 0x96, 0xaf, 0xad, 0x31, 0x75, 0x39, 0xc9, 0xe5, 0x82, 0x1f, 0x87, 0x9d, + 0xd9, 0x07, 0xc5, 0x3b, 0x8d, 0x5f, 0xbe, 0xb1, 0x66, 0x42, 0x71, 0xba, 0x53, 0x67, 0x3f, 0x61, + 0xc1, 0xe9, 0x2c, 0x12, 0xe8, 0x04, 0x14, 0xb7, 0x48, 0x87, 0x5b, 0xa2, 0x98, 0xfe, 0x44, 0x2f, + 0x43, 0x69, 0xdb, 0xf1, 0xda, 0x44, 0x98, 0x69, 0x0b, 0x87, 0x7b, 0x11, 0xd5, 0x33, 0xcc, 0xa9, + 0xfe, 0x58, 0xe1, 0x79, 0xcb, 0xfe, 0xc3, 0x22, 0x0c, 0x1b, 0x1f, 0xed, 0x18, 0x4c, 0xcf, 0x20, + 0x61, 0x7a, 0x2e, 0xe7, 0x36, 0xdf, 0x7a, 0xda, 0x9e, 0xb7, 0x52, 0xb6, 0xe7, 0x4a, 0x7e, 0x2c, + 0xf7, 0x34, 0x3e, 0x51, 0x0c, 0x95, 0xa0, 0x45, 0xb7, 0x21, 0xd4, 0x86, 0x19, 0xc8, 0xe3, 0x13, + 0xae, 0x48, 0x72, 0xb3, 0xa3, 0xb7, 0x77, 0x27, 0x2b, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x59, + 0x70, 0xda, 0xe8, 0xe3, 0x5c, 0xe0, 0xd7, 0x5d, 0xf6, 0x69, 0xcf, 0xc1, 0x40, 0xdc, 0x69, 0xc9, + 0xad, 0x8e, 0x1a, 0xa9, 0xb5, 0x4e, 0x8b, 0x60, 0x06, 0xa1, 0x3b, 0x96, 0x26, 0x89, 0x22, 0xa7, + 0x41, 0xd2, 0x9b, 0x9b, 0x65, 0xde, 0x8c, 0x25, 0x1c, 0x85, 0x80, 0x3c, 0x27, 0x8a, 0xd7, 0x42, + 0xc7, 0x8f, 0x18, 0xf9, 0x35, 0xb7, 0x49, 0xc4, 0x00, 0xff, 0x7f, 0xfd, 0xcd, 0x18, 0xfa, 0xc4, + 0xec, 0x03, 0xb7, 0x77, 0x27, 0xd1, 0x52, 0x17, 0x25, 0x9c, 0x41, 0xdd, 0xfe, 0xbc, 0x05, 0x0f, + 0x64, 0x0b, 0x18, 0xf4, 0x04, 0x0c, 0xf2, 0x7d, 0xae, 0x78, 0x3b, 0xfd, 0x49, 0x58, 0x2b, 0x16, + 0x50, 0x34, 0x0d, 0x15, 0xa5, 0xf0, 0xc4, 0x3b, 0x9e, 0x14, 0xa8, 0x15, 0xad, 0x25, 0x35, 0x0e, + 0x1d, 0x34, 0xfa, 0x47, 0x98, 0xa0, 0x6a, 0xd0, 0xd8, 0xc6, 0x90, 0x41, 0xec, 0x6f, 0x5a, 0xf0, + 0xe6, 0x7e, 0xc4, 0xde, 0xd1, 0xf5, 0xb1, 0x0a, 0x67, 0xea, 0x64, 0xc3, 0x69, 0x7b, 0x71, 0x92, + 0xa3, 0xe8, 0xf4, 0xa3, 0xe2, 0xe1, 0x33, 0xf3, 0x59, 0x48, 0x38, 0xfb, 0x59, 0xfb, 0xbf, 0x58, + 0x30, 0x6e, 0xbc, 0xd6, 0x31, 0x6c, 0x9d, 0xfc, 0xe4, 0xd6, 0x69, 0x31, 0xb7, 0x65, 0xda, 0x63, + 0xef, 0xf4, 0x29, 0x0b, 0xce, 0x1a, 0x58, 0xcb, 0x4e, 0x5c, 0xdb, 0xbc, 0xb0, 0xd3, 0x0a, 0x49, + 0x14, 0xd1, 0x29, 0xf5, 0xa8, 0x21, 0x8e, 0x67, 0x87, 0x05, 0x85, 0xe2, 0x15, 0xd2, 0xe1, 0xb2, + 0xf9, 0x29, 0x28, 0xf3, 0x35, 0x17, 0x84, 0xe2, 0x23, 0xa9, 0x77, 0x5b, 0x11, 0xed, 0x58, 0x61, + 0x20, 0x1b, 0x06, 0x99, 0xcc, 0xa5, 0x32, 0x88, 0x9a, 0x09, 0x40, 0xbf, 0xfb, 0x75, 0xd6, 0x82, + 0x05, 0xc4, 0x8e, 0x12, 0xdd, 0x59, 0x0d, 0x09, 0x9b, 0x0f, 0xf5, 0x8b, 0x2e, 0xf1, 0xea, 0x11, + 0xdd, 0xd6, 0x39, 0xbe, 0x1f, 0xc4, 0x62, 0x87, 0x66, 0x6c, 0xeb, 0x66, 0x74, 0x33, 0x36, 0x71, + 0x28, 0x53, 0xcf, 0x59, 0x27, 0x1e, 0x1f, 0x51, 0xc1, 0x74, 0x89, 0xb5, 0x60, 0x01, 0xb1, 0x6f, + 0x17, 0xd8, 0x06, 0x52, 0x49, 0x34, 0x72, 0x1c, 0xde, 0x87, 0x30, 0xa1, 0x02, 0x56, 0xf3, 0x93, + 0xc7, 0xa4, 0xb7, 0x07, 0xe2, 0xb5, 0x94, 0x16, 0xc0, 0xb9, 0x72, 0xdd, 0xdb, 0x0b, 0xf1, 0xa1, + 0x22, 0x4c, 0x26, 0x1f, 0xe8, 0x52, 0x22, 0x74, 0xcb, 0x6b, 0x30, 0x4a, 0xfb, 0xa3, 0x0c, 0x7c, + 0x6c, 0xe2, 0xf5, 0x90, 0xc3, 0x85, 0xa3, 0x94, 0xc3, 0xa6, 0x9a, 0x28, 0xee, 0xa3, 0x26, 0x9e, + 0x50, 0xa3, 0x3e, 0x90, 0x92, 0x79, 0x49, 0x55, 0x79, 0x0e, 0x06, 0xa2, 0x98, 0xb4, 0x26, 0x4a, + 0x49, 0x31, 0x5b, 0x8d, 0x49, 0x0b, 0x33, 0x08, 0x7a, 0x3b, 0x8c, 0xc7, 0x4e, 0xd8, 0x20, 0x71, + 0x48, 0xb6, 0x5d, 0xe6, 0xbb, 0x64, 0xfb, 0xd9, 0xca, 0xec, 0x29, 0x6a, 0x75, 0xad, 0x31, 0x10, + 0x96, 0x20, 0x9c, 0xc6, 0xb5, 0xff, 0x7b, 0x01, 0x1e, 0x4c, 0x7e, 0x02, 0xad, 0x18, 0xdf, 0x99, + 0x50, 0x8c, 0x6f, 0x35, 0x15, 0xe3, 0x9d, 0xdd, 0xc9, 0x87, 0x7b, 0x3c, 0xf6, 0x3d, 0xa3, 0x37, + 0xd1, 0x42, 0xea, 0x23, 0x4c, 0x27, 0x3f, 0xc2, 0x9d, 0xdd, 0xc9, 0x47, 0x7b, 0xbc, 0x63, 0xea, + 0x2b, 0x3d, 0x01, 0x83, 0x21, 0x71, 0xa2, 0xc0, 0x17, 0xdf, 0x49, 0x7d, 0x4d, 0xcc, 0x5a, 0xb1, + 0x80, 0xda, 0xdf, 0xa8, 0xa4, 0x07, 0x7b, 0x81, 0xfb, 0x63, 0x83, 0x10, 0xb9, 0x30, 0xc0, 0x76, + 0x6d, 0x5c, 0xb2, 0x5c, 0x39, 0xdc, 0x2a, 0xa4, 0x5a, 0x44, 0x91, 0x9e, 0x2d, 0xd3, 0xaf, 0x46, + 0x9b, 0x30, 0x63, 0x81, 0x76, 0xa0, 0x5c, 0x93, 0x9b, 0xa9, 0x42, 0x1e, 0x6e, 0x47, 0xb1, 0x95, + 0xd2, 0x1c, 0x47, 0xa8, 0xb8, 0x57, 0x3b, 0x30, 0xc5, 0x0d, 0x11, 0x28, 0x36, 0xdc, 0x58, 0x7c, + 0xd6, 0x43, 0x6e, 0x97, 0x17, 0x5c, 0xe3, 0x15, 0x87, 0xa8, 0x0e, 0x5a, 0x70, 0x63, 0x4c, 0xe9, + 0xa3, 0x8f, 0x59, 0x30, 0x1c, 0xd5, 0x9a, 0xab, 0x61, 0xb0, 0xed, 0xd6, 0x49, 0x28, 0x6c, 0xcc, + 0x43, 0x4a, 0xb6, 0xea, 0xdc, 0xb2, 0x24, 0xa8, 0xf9, 0x72, 0xf7, 0x85, 0x86, 0x60, 0x93, 0x2f, + 0xdd, 0x7b, 0x3d, 0x28, 0xde, 0x7d, 0x9e, 0xd4, 0xd8, 0x8a, 0x93, 0x7b, 0x66, 0x36, 0x53, 0x0e, + 0x6d, 0x73, 0xcf, 0xb7, 0x6b, 0x5b, 0x74, 0xbd, 0xe9, 0x0e, 0x3d, 0x7c, 0x7b, 0x77, 0xf2, 0xc1, + 0xb9, 0x6c, 0x9e, 0xb8, 0x57, 0x67, 0xd8, 0x80, 0xb5, 0xda, 0x9e, 0x87, 0xc9, 0xab, 0x6d, 0xc2, + 0x3c, 0x62, 0x39, 0x0c, 0xd8, 0xaa, 0x26, 0x98, 0x1a, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x55, + 0x18, 0x6c, 0x3a, 0x71, 0xe8, 0xee, 0x08, 0x37, 0xd8, 0x21, 0x77, 0x41, 0xcb, 0x8c, 0x96, 0x66, + 0xce, 0x14, 0x3d, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x42, 0xa9, 0x49, 0xc2, 0x06, 0x99, 0x28, 0xe7, + 0xe1, 0xf2, 0x5f, 0xa6, 0xa4, 0x34, 0xc3, 0x0a, 0x35, 0xae, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0xcb, + 0x50, 0x8e, 0x88, 0x47, 0x6a, 0xd4, 0x3c, 0xaa, 0x30, 0x8e, 0x3f, 0xd2, 0xa7, 0xa9, 0x48, 0xed, + 0x92, 0xaa, 0x78, 0x94, 0x2f, 0x30, 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x5b, 0x5e, 0xbb, 0xe1, + 0xfa, 0x13, 0x90, 0xc7, 0x00, 0xae, 0x32, 0x5a, 0xa9, 0x01, 0xe4, 0x8d, 0x58, 0x30, 0xb2, 0xff, + 0x9b, 0x05, 0x28, 0x29, 0xd4, 0x8e, 0xc1, 0x26, 0x7e, 0x35, 0x69, 0x13, 0x2f, 0xe5, 0x69, 0xb4, + 0xf4, 0x30, 0x8b, 0x7f, 0xb3, 0x02, 0x29, 0x75, 0x70, 0x95, 0x44, 0x31, 0xa9, 0xbf, 0x21, 0xc2, + 0xdf, 0x10, 0xe1, 0x6f, 0x88, 0x70, 0x25, 0xc2, 0xd7, 0x53, 0x22, 0xfc, 0x1d, 0xc6, 0xaa, 0xd7, + 0xe7, 0xeb, 0xaf, 0xa8, 0x03, 0x78, 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x97, 0xab, 0x2b, 0x57, + 0x33, 0x65, 0xf6, 0x2b, 0x49, 0x99, 0x7d, 0x58, 0x16, 0x7f, 0x1b, 0xa4, 0xf4, 0xef, 0x5b, 0xf0, + 0x96, 0xa4, 0xf4, 0x92, 0x33, 0x67, 0xb1, 0xe1, 0x07, 0x21, 0x99, 0x77, 0x37, 0x36, 0x48, 0x48, + 0xfc, 0x1a, 0x89, 0x94, 0x6f, 0xc7, 0xea, 0xe5, 0xdb, 0x41, 0xcf, 0xc2, 0xc8, 0xcd, 0x28, 0xf0, + 0x57, 0x03, 0xd7, 0x17, 0x22, 0x88, 0xee, 0x38, 0x4e, 0xdc, 0xde, 0x9d, 0x1c, 0xa1, 0x23, 0x2a, + 0xdb, 0x71, 0x02, 0x0b, 0xcd, 0xc1, 0xc9, 0x9b, 0xaf, 0xae, 0x3a, 0xb1, 0xe1, 0x4d, 0x90, 0xfb, + 0x7e, 0x76, 0x1e, 0x75, 0xf9, 0xc5, 0x14, 0x10, 0x77, 0xe3, 0xdb, 0xff, 0xa0, 0x00, 0x0f, 0xa5, + 0x5e, 0x24, 0xf0, 0xbc, 0xa0, 0x1d, 0xd3, 0x3d, 0x11, 0xfa, 0xa2, 0x05, 0x27, 0x9a, 0x49, 0x87, + 0x45, 0x24, 0xdc, 0xdd, 0xef, 0xca, 0x4d, 0x47, 0xa4, 0x3c, 0x22, 0xb3, 0x13, 0x62, 0x84, 0x4e, + 0xa4, 0x00, 0x11, 0xee, 0xea, 0x0b, 0x7a, 0x19, 0x2a, 0x4d, 0x67, 0xe7, 0x5a, 0xab, 0xee, 0xc4, + 0x72, 0x3b, 0xda, 0xdb, 0x8b, 0xd0, 0x8e, 0x5d, 0x6f, 0x8a, 0x47, 0x6e, 0x4c, 0x2d, 0xfa, 0xf1, + 0x4a, 0x58, 0x8d, 0x43, 0xd7, 0x6f, 0x70, 0x27, 0xe7, 0xb2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0x0b, + 0x56, 0x5a, 0x49, 0xa9, 0xd1, 0x09, 0x9d, 0x98, 0x34, 0x3a, 0xe8, 0xfd, 0x50, 0xa2, 0xfb, 0x46, + 0x39, 0x2a, 0x37, 0xf2, 0xd4, 0x9c, 0xc6, 0x97, 0xd0, 0x4a, 0x94, 0xfe, 0x8b, 0x30, 0x67, 0x6a, + 0x7f, 0xb1, 0x92, 0x36, 0x16, 0xd8, 0xd9, 0xfc, 0x79, 0x80, 0x46, 0xb0, 0x46, 0x9a, 0x2d, 0x8f, + 0x0e, 0x8b, 0xc5, 0x0e, 0x78, 0x94, 0xab, 0x64, 0x41, 0x41, 0xb0, 0x81, 0x85, 0x7e, 0xde, 0x02, + 0x68, 0xc8, 0x39, 0x2f, 0x0d, 0x81, 0x6b, 0x79, 0xbe, 0x8e, 0x5e, 0x51, 0xba, 0x2f, 0x8a, 0x21, + 0x36, 0x98, 0xa3, 0x9f, 0xb1, 0xa0, 0x1c, 0xcb, 0xee, 0x73, 0xd5, 0xb8, 0x96, 0x67, 0x4f, 0xe4, + 0x4b, 0x6b, 0x9b, 0x48, 0x0d, 0x89, 0xe2, 0x8b, 0x7e, 0xd6, 0x02, 0x88, 0x3a, 0x7e, 0x6d, 0x35, + 0xf0, 0xdc, 0x5a, 0x47, 0x68, 0xcc, 0xeb, 0xb9, 0xba, 0x73, 0x14, 0xf5, 0xd9, 0x31, 0x3a, 0x1a, + 0xfa, 0x3f, 0x36, 0x38, 0xa3, 0x0f, 0x42, 0x39, 0x12, 0xd3, 0x4d, 0xe8, 0xc8, 0xb5, 0x7c, 0x9d, + 0x4a, 0x9c, 0xb6, 0x10, 0xaf, 0xe2, 0x1f, 0x56, 0x3c, 0xd1, 0x2f, 0x5a, 0x30, 0xde, 0x4a, 0xba, + 0x09, 0x85, 0x3a, 0xcc, 0x4f, 0x06, 0xa4, 0xdc, 0x90, 0xdc, 0xdb, 0x92, 0x6a, 0xc4, 0xe9, 0x5e, + 0x50, 0x09, 0xa8, 0x67, 0xf0, 0x4a, 0x8b, 0xbb, 0x2c, 0x87, 0xb4, 0x04, 0x5c, 0x48, 0x03, 0x71, + 0x37, 0x3e, 0x5a, 0x85, 0xd3, 0xb4, 0x77, 0x1d, 0x6e, 0x7e, 0x4a, 0xf5, 0x12, 0x31, 0x65, 0x58, + 0x9e, 0x7d, 0x44, 0xcc, 0x10, 0x76, 0xd6, 0x91, 0xc6, 0xc1, 0x99, 0x4f, 0xa2, 0x3f, 0xb4, 0xe0, + 0x11, 0x97, 0xa9, 0x01, 0xd3, 0x61, 0xaf, 0x35, 0x82, 0x38, 0x68, 0x27, 0xb9, 0xca, 0x8a, 0x5e, + 0xea, 0x67, 0xf6, 0xcd, 0xe2, 0x0d, 0x1e, 0x59, 0xdc, 0xa3, 0x4b, 0x78, 0xcf, 0x0e, 0xa3, 0x1f, + 0x85, 0x51, 0xb9, 0x2e, 0x56, 0xa9, 0x08, 0x66, 0x8a, 0xb6, 0x32, 0x7b, 0xf2, 0xf6, 0xee, 0xe4, + 0xe8, 0x9a, 0x09, 0xc0, 0x49, 0x3c, 0xfb, 0xdf, 0x15, 0x13, 0xa7, 0x44, 0xca, 0x87, 0xc9, 0xc4, + 0x4d, 0x4d, 0xfa, 0x7f, 0xa4, 0xf4, 0xcc, 0x55, 0xdc, 0x28, 0xef, 0x92, 0x16, 0x37, 0xaa, 0x29, + 0xc2, 0x06, 0x73, 0x6a, 0x94, 0x9e, 0x74, 0xd2, 0x9e, 0x52, 0x21, 0x01, 0x5f, 0xce, 0xb3, 0x4b, + 0xdd, 0x67, 0x7a, 0x0f, 0x89, 0xae, 0x9d, 0xec, 0x02, 0xe1, 0xee, 0x2e, 0xa1, 0x0f, 0x40, 0x25, + 0x54, 0x91, 0x2d, 0xc5, 0x3c, 0xb6, 0x6a, 0x72, 0xda, 0x88, 0xee, 0xa8, 0x03, 0x20, 0x1d, 0xc3, + 0xa2, 0x39, 0xda, 0x7f, 0x90, 0x3c, 0x18, 0x33, 0x64, 0x47, 0x1f, 0x87, 0x7e, 0x9f, 0xb6, 0x60, + 0x38, 0x0c, 0x3c, 0xcf, 0xf5, 0x1b, 0x54, 0xce, 0x09, 0x65, 0xfd, 0x9e, 0x23, 0xd1, 0x97, 0x42, + 0xa0, 0x31, 0xcb, 0x1a, 0x6b, 0x9e, 0xd8, 0xec, 0x80, 0xfd, 0x67, 0x16, 0x4c, 0xf4, 0x92, 0xc7, + 0x88, 0xc0, 0xc3, 0x52, 0xd8, 0xa8, 0xa1, 0x58, 0xf1, 0xe7, 0x89, 0x47, 0x94, 0xdb, 0xbc, 0x3c, + 0xfb, 0xb8, 0x78, 0xcd, 0x87, 0x57, 0x7b, 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x97, 0xe0, 0x84, 0xf1, + 0x5e, 0x91, 0x1a, 0x98, 0xca, 0xec, 0x14, 0x35, 0x80, 0x66, 0x52, 0xb0, 0x3b, 0xbb, 0x93, 0x0f, + 0xa4, 0xdb, 0x84, 0xc2, 0xe8, 0xa2, 0x63, 0x7f, 0xa5, 0x90, 0xfe, 0x5a, 0x4a, 0xd7, 0xbf, 0x6e, + 0x75, 0x79, 0x13, 0xde, 0x75, 0x14, 0xfa, 0x95, 0xf9, 0x1d, 0x54, 0x18, 0x46, 0x6f, 0x9c, 0x7b, + 0x78, 0x6c, 0x6f, 0xff, 0xfb, 0x01, 0xd8, 0xa3, 0x67, 0x7d, 0x18, 0xef, 0x07, 0x3e, 0x47, 0xfd, + 0xa4, 0xa5, 0x0e, 0xcc, 0xf8, 0x1a, 0xae, 0x1f, 0xd5, 0xd8, 0xf3, 0xfd, 0x53, 0xc4, 0x43, 0x47, + 0x94, 0x17, 0x3d, 0x79, 0x34, 0x87, 0xbe, 0x64, 0x25, 0x8f, 0xfc, 0x78, 0x50, 0xa3, 0x7b, 0x64, + 0x7d, 0x32, 0xce, 0x11, 0x79, 0xc7, 0xf4, 0xe9, 0x53, 0xaf, 0x13, 0xc6, 0x29, 0x80, 0x0d, 0xd7, + 0x77, 0x3c, 0xf7, 0x35, 0xba, 0x3b, 0x2a, 0x31, 0x05, 0xcf, 0x2c, 0xa6, 0x8b, 0xaa, 0x15, 0x1b, + 0x18, 0x67, 0xff, 0x7f, 0x18, 0x36, 0xde, 0x3c, 0x23, 0xe2, 0xe5, 0xb4, 0x19, 0xf1, 0x52, 0x31, + 0x02, 0x55, 0xce, 0xbe, 0x03, 0x4e, 0xa4, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x3d, 0x94, 0x3e, + 0x83, 0x5b, 0x23, 0x61, 0x93, 0x76, 0xed, 0x0d, 0xc7, 0xd6, 0x1b, 0x8e, 0xad, 0x37, 0x1c, 0x5b, + 0xe6, 0xd9, 0x84, 0x70, 0xda, 0x0c, 0x1d, 0x93, 0xd3, 0x26, 0xe1, 0x86, 0x2a, 0xe7, 0xee, 0x86, + 0xb2, 0x3f, 0xd6, 0xe5, 0xb9, 0x5f, 0x0b, 0x09, 0x41, 0x01, 0x94, 0xfc, 0xa0, 0x4e, 0xa4, 0x8d, + 0x7b, 0x39, 0x1f, 0x83, 0xed, 0x6a, 0x50, 0x37, 0xc2, 0xc5, 0xe9, 0xbf, 0x08, 0x73, 0x3e, 0xf6, + 0x47, 0x07, 0x21, 0x61, 0x4e, 0xf2, 0xef, 0xfe, 0x43, 0x30, 0x14, 0x92, 0x56, 0x70, 0x0d, 0x2f, + 0x09, 0x5d, 0xa6, 0x33, 0x4a, 0x78, 0x33, 0x96, 0x70, 0xaa, 0xf3, 0x5a, 0x4e, 0xbc, 0x29, 0x94, + 0x99, 0xd2, 0x79, 0xab, 0x4e, 0xbc, 0x89, 0x19, 0x04, 0xbd, 0x03, 0xc6, 0xe2, 0xc4, 0x51, 0xb8, + 0x38, 0xf2, 0x7d, 0x40, 0xe0, 0x8e, 0x25, 0x0f, 0xca, 0x71, 0x0a, 0x1b, 0xbd, 0x0a, 0x03, 0x9b, + 0xc4, 0x6b, 0x8a, 0x4f, 0x5f, 0xcd, 0x4f, 0xd7, 0xb0, 0x77, 0xbd, 0x44, 0xbc, 0x26, 0x97, 0x84, + 0xf4, 0x17, 0x66, 0xac, 0xe8, 0xbc, 0xaf, 0x6c, 0xb5, 0xa3, 0x38, 0x68, 0xba, 0xaf, 0x49, 0x4f, + 0xe7, 0xbb, 0x72, 0x66, 0x7c, 0x45, 0xd2, 0xe7, 0x2e, 0x25, 0xf5, 0x17, 0x6b, 0xce, 0xac, 0x1f, + 0x75, 0x37, 0x64, 0x53, 0xa6, 0x23, 0x1c, 0x96, 0x79, 0xf7, 0x63, 0x5e, 0xd2, 0xe7, 0xfd, 0x50, + 0x7f, 0xb1, 0xe6, 0x8c, 0x3a, 0x6a, 0xfd, 0x0d, 0xb3, 0x3e, 0x5c, 0xcb, 0xb9, 0x0f, 0x7c, 0xed, + 0x65, 0xae, 0xc3, 0xc7, 0xa1, 0x54, 0xdb, 0x74, 0xc2, 0x78, 0x62, 0x84, 0x4d, 0x1a, 0x35, 0x8b, + 0xe7, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x28, 0x14, 0x43, 0xb2, 0xc1, 0xa2, 0x93, 0x8d, 0xb8, 0x28, + 0x4c, 0x36, 0x30, 0x6d, 0x57, 0x76, 0xd9, 0x58, 0xcf, 0x80, 0xb9, 0x5f, 0x29, 0x24, 0x0d, 0xbb, + 0xe4, 0xc8, 0xf0, 0xf5, 0x50, 0x6b, 0x87, 0x91, 0x74, 0x90, 0x19, 0xeb, 0x81, 0x35, 0x63, 0x09, + 0x47, 0x1f, 0xb6, 0x60, 0xe8, 0x66, 0x14, 0xf8, 0x3e, 0x89, 0x85, 0x12, 0xbd, 0x9e, 0xf3, 0x60, + 0x5d, 0xe6, 0xd4, 0x75, 0x1f, 0x44, 0x03, 0x96, 0x7c, 0x69, 0x77, 0xc9, 0x4e, 0xcd, 0x6b, 0xd7, + 0xbb, 0x82, 0x61, 0x2e, 0xf0, 0x66, 0x2c, 0xe1, 0x14, 0xd5, 0xf5, 0x39, 0xea, 0x40, 0x12, 0x75, + 0xd1, 0x17, 0xa8, 0x02, 0x6e, 0xff, 0x7a, 0x19, 0xce, 0x64, 0x2e, 0x1f, 0x6a, 0x72, 0x31, 0xa3, + 0xe6, 0xa2, 0xeb, 0x11, 0x19, 0x06, 0xc6, 0x4c, 0xae, 0xeb, 0xaa, 0x15, 0x1b, 0x18, 0xe8, 0xa7, + 0x01, 0x5a, 0x4e, 0xe8, 0x34, 0x89, 0x72, 0x60, 0x1f, 0xda, 0xb2, 0xa1, 0xfd, 0x58, 0x95, 0x34, + 0xf5, 0x26, 0x5e, 0x35, 0x45, 0xd8, 0x60, 0x89, 0x9e, 0x83, 0xe1, 0x90, 0x78, 0xc4, 0x89, 0x58, + 0xf8, 0x7b, 0x3a, 0x97, 0x07, 0x6b, 0x10, 0x36, 0xf1, 0xd0, 0x13, 0x2a, 0x62, 0x2e, 0x15, 0x39, + 0x94, 0x8c, 0x9a, 0x43, 0x9f, 0xb1, 0x60, 0x6c, 0xc3, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x6f, 0x56, + 0x0e, 0xff, 0x92, 0x17, 0x4d, 0xba, 0x5a, 0x86, 0x26, 0x9a, 0x23, 0x9c, 0x62, 0x4f, 0x3f, 0xf3, + 0x36, 0x09, 0x99, 0xf0, 0x1d, 0x4c, 0x7e, 0xe6, 0xeb, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x81, 0xf1, + 0x96, 0x13, 0x45, 0x73, 0x21, 0xa9, 0x13, 0x3f, 0x76, 0x1d, 0x8f, 0xe7, 0xc5, 0x94, 0x75, 0x38, + 0xf9, 0x6a, 0x12, 0x8c, 0xd3, 0xf8, 0xe8, 0xdd, 0xf0, 0x20, 0xf7, 0x10, 0x2d, 0xbb, 0x51, 0xe4, + 0xfa, 0x0d, 0x3d, 0x0d, 0x84, 0xa3, 0x6c, 0x52, 0x90, 0x7a, 0x70, 0x31, 0x1b, 0x0d, 0xf7, 0x7a, + 0x1e, 0x3d, 0x05, 0xe5, 0x68, 0xcb, 0x6d, 0xcd, 0x85, 0xf5, 0x88, 0x9d, 0x0e, 0x95, 0xb5, 0x5b, + 0xb6, 0x2a, 0xda, 0xb1, 0xc2, 0x40, 0x35, 0x18, 0xe1, 0x9f, 0x84, 0x87, 0xfc, 0x09, 0x09, 0xfa, + 0x74, 0x4f, 0x45, 0x2e, 0xd2, 0x3c, 0xa7, 0xb0, 0x73, 0xeb, 0x82, 0x3c, 0xab, 0xe2, 0x47, 0x2b, + 0xd7, 0x0d, 0x32, 0x38, 0x41, 0x34, 0xb9, 0xa7, 0x1b, 0xee, 0x63, 0x4f, 0xf7, 0x1c, 0x0c, 0x6f, + 0xb5, 0xd7, 0x89, 0x18, 0x79, 0x21, 0xd8, 0xd4, 0xec, 0xbb, 0xa2, 0x41, 0xd8, 0xc4, 0x63, 0xd1, + 0x96, 0x2d, 0x57, 0xfc, 0x8b, 0x26, 0x46, 0x8d, 0x68, 0xcb, 0xd5, 0x45, 0xd9, 0x8c, 0x4d, 0x1c, + 0xda, 0x35, 0x3a, 0x16, 0x6b, 0x24, 0x62, 0xc9, 0x14, 0x74, 0xb8, 0x54, 0xd7, 0xaa, 0x12, 0x80, + 0x35, 0x0e, 0x5a, 0x85, 0xd3, 0xf4, 0x4f, 0x95, 0xa5, 0xb9, 0x5e, 0x77, 0x3c, 0xb7, 0xce, 0x43, + 0xff, 0xc6, 0x93, 0xfe, 0xcd, 0x6a, 0x06, 0x0e, 0xce, 0x7c, 0xd2, 0xfe, 0xa5, 0x42, 0xd2, 0x73, + 0x62, 0x8a, 0x30, 0x14, 0x51, 0x41, 0x15, 0x5f, 0x77, 0x42, 0x69, 0xf0, 0x1c, 0x32, 0xb9, 0x49, + 0xd0, 0xbd, 0xee, 0x84, 0xa6, 0xc8, 0x63, 0x0c, 0xb0, 0xe4, 0x84, 0x6e, 0xc2, 0x40, 0xec, 0x39, + 0x39, 0x65, 0x43, 0x1a, 0x1c, 0xb5, 0x23, 0x6b, 0x69, 0x26, 0xc2, 0x8c, 0x07, 0x7a, 0x84, 0xee, + 0xde, 0xd6, 0xe5, 0x49, 0x9b, 0xd8, 0x70, 0xad, 0x47, 0x98, 0xb5, 0xda, 0x7f, 0x3e, 0x9c, 0xa1, + 0x75, 0x94, 0x21, 0x80, 0xce, 0x03, 0xd0, 0x49, 0xb3, 0x1a, 0x92, 0x0d, 0x77, 0x47, 0x18, 0x62, + 0x4a, 0xb2, 0x5d, 0x55, 0x10, 0x6c, 0x60, 0xc9, 0x67, 0xaa, 0xed, 0x0d, 0xfa, 0x4c, 0xa1, 0xfb, + 0x19, 0x0e, 0xc1, 0x06, 0x16, 0x7a, 0x16, 0x06, 0xdd, 0xa6, 0xd3, 0x50, 0x81, 0xc0, 0x8f, 0x50, + 0x91, 0xb6, 0xc8, 0x5a, 0xee, 0xec, 0x4e, 0x8e, 0xa9, 0x0e, 0xb1, 0x26, 0x2c, 0x70, 0xd1, 0x57, + 0x2c, 0x18, 0xa9, 0x05, 0xcd, 0x66, 0xe0, 0xf3, 0xed, 0xb3, 0xf0, 0x05, 0xdc, 0x3c, 0x2a, 0x33, + 0x69, 0x6a, 0xce, 0x60, 0xc6, 0x9d, 0x01, 0x2a, 0x6d, 0xd3, 0x04, 0xe1, 0x44, 0xaf, 0x4c, 0xc9, + 0x57, 0xda, 0x47, 0xf2, 0xfd, 0x86, 0x05, 0x27, 0xf9, 0xb3, 0xc6, 0xae, 0x5e, 0x64, 0x28, 0x06, + 0x47, 0xfc, 0x5a, 0x5d, 0x8e, 0x0e, 0xe5, 0xec, 0xed, 0x82, 0xe3, 0xee, 0x4e, 0xa2, 0x05, 0x38, + 0xb9, 0x11, 0x84, 0x35, 0x62, 0x0e, 0x84, 0x10, 0xdb, 0x8a, 0xd0, 0xc5, 0x34, 0x02, 0xee, 0x7e, + 0x06, 0x5d, 0x87, 0x07, 0x8c, 0x46, 0x73, 0x1c, 0xb8, 0xe4, 0x7e, 0x4c, 0x50, 0x7b, 0xe0, 0x62, + 0x26, 0x16, 0xee, 0xf1, 0x74, 0x52, 0x48, 0x56, 0xfa, 0x10, 0x92, 0xaf, 0xc0, 0x43, 0xb5, 0xee, + 0x91, 0xd9, 0x8e, 0xda, 0xeb, 0x11, 0x97, 0xe3, 0xe5, 0xd9, 0x1f, 0x10, 0x04, 0x1e, 0x9a, 0xeb, + 0x85, 0x88, 0x7b, 0xd3, 0x40, 0xef, 0x87, 0x72, 0x48, 0xd8, 0x57, 0x89, 0x44, 0xba, 0xde, 0x21, + 0xbd, 0x1d, 0xda, 0x82, 0xe7, 0x64, 0xb5, 0x66, 0x12, 0x0d, 0x11, 0x56, 0x1c, 0xd1, 0x2d, 0x18, + 0x6a, 0x39, 0x71, 0x6d, 0x53, 0x24, 0xe9, 0x1d, 0xda, 0x37, 0xaf, 0x98, 0xb3, 0xa3, 0x14, 0x23, + 0xad, 0x9f, 0x33, 0xc1, 0x92, 0x1b, 0xb5, 0xd5, 0x6a, 0x41, 0xb3, 0x15, 0xf8, 0xc4, 0x8f, 0xa5, + 0x12, 0x19, 0xe3, 0xe7, 0x1d, 0xb2, 0x15, 0x1b, 0x18, 0x54, 0x23, 0x30, 0xdf, 0xdf, 0x0d, 0x37, + 0xde, 0x0c, 0xda, 0xb1, 0xdc, 0xca, 0x0a, 0x6d, 0xa2, 0x34, 0xc2, 0x52, 0x06, 0x0e, 0xce, 0x7c, + 0x32, 0xad, 0xfe, 0xc6, 0xef, 0x4e, 0xfd, 0x9d, 0xd8, 0x5f, 0xfd, 0x9d, 0x7d, 0x27, 0x9c, 0xec, + 0x12, 0x1a, 0x07, 0x72, 0xf0, 0xcd, 0xc3, 0x03, 0xd9, 0xcb, 0xf3, 0x40, 0x6e, 0xbe, 0x5f, 0x4f, + 0xc5, 0x79, 0x1b, 0x5b, 0x9e, 0x3e, 0x5c, 0xc6, 0x0e, 0x14, 0x89, 0xbf, 0x2d, 0xb4, 0xd5, 0xc5, + 0xc3, 0xcd, 0x92, 0x0b, 0xfe, 0x36, 0x97, 0x2e, 0xcc, 0x2f, 0x76, 0xc1, 0xdf, 0xc6, 0x94, 0x36, + 0xfa, 0x9c, 0x95, 0x30, 0xc8, 0xb9, 0xa3, 0xf9, 0xbd, 0x47, 0xb2, 0xc7, 0xeb, 0xdb, 0x46, 0xb7, + 0xff, 0x43, 0x01, 0xce, 0xed, 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x1c, 0x06, 0x23, 0x16, 0xb9, 0x21, + 0xc4, 0xff, 0x30, 0x5d, 0x15, 0x3c, 0x96, 0xe3, 0x15, 0x2c, 0x40, 0xc8, 0x83, 0x62, 0xd3, 0x69, + 0x09, 0xff, 0xe3, 0xe2, 0x61, 0xf3, 0xe1, 0xe8, 0x7f, 0xc7, 0x5b, 0x76, 0x5a, 0x7c, 0x7a, 0x1a, + 0x0d, 0x98, 0xb2, 0x41, 0x31, 0x94, 0x9c, 0x30, 0x74, 0x64, 0x98, 0xc0, 0x95, 0x7c, 0xf8, 0xcd, + 0x50, 0x92, 0xfc, 0x94, 0x35, 0xd1, 0x84, 0x39, 0x33, 0xfb, 0x17, 0xcb, 0x89, 0xe4, 0x29, 0x16, + 0xfb, 0x11, 0xc1, 0xa0, 0x70, 0x3b, 0x5a, 0x79, 0xa7, 0x21, 0xf2, 0xec, 0x64, 0xb6, 0xa3, 0x17, + 0x35, 0x1e, 0x04, 0x2b, 0xf4, 0x09, 0x8b, 0x55, 0x52, 0x90, 0x19, 0x69, 0x62, 0x97, 0x7c, 0x34, + 0x85, 0x1d, 0xcc, 0xfa, 0x0c, 0xb2, 0x11, 0x9b, 0xdc, 0x45, 0x45, 0x14, 0xb6, 0x3b, 0xe8, 0xae, + 0x88, 0xc2, 0xac, 0x7d, 0x09, 0x47, 0x3b, 0x19, 0x31, 0x1e, 0x39, 0x64, 0xe3, 0xf7, 0x11, 0xd5, + 0xf1, 0x25, 0x0b, 0x4e, 0xba, 0xe9, 0xc3, 0x7a, 0xb1, 0xa7, 0xbc, 0x91, 0x8f, 0x8f, 0xb0, 0x3b, + 0x16, 0x40, 0x19, 0x0e, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0x54, 0x87, 0x01, 0xd7, 0xdf, 0x08, 0x84, + 0xb9, 0x34, 0x7b, 0xb8, 0x4e, 0x2d, 0xfa, 0x1b, 0x81, 0x5e, 0xcd, 0xf4, 0x1f, 0x66, 0xd4, 0xd1, + 0x12, 0x9c, 0x96, 0xf9, 0x33, 0x97, 0xdc, 0x28, 0x0e, 0xc2, 0xce, 0x92, 0xdb, 0x74, 0x63, 0x66, + 0xea, 0x14, 0x67, 0x27, 0xa8, 0x26, 0xc2, 0x19, 0x70, 0x9c, 0xf9, 0x14, 0x7a, 0x0d, 0x86, 0xe4, + 0x01, 0x79, 0x39, 0x8f, 0xfd, 0x79, 0xf7, 0xfc, 0x57, 0x93, 0xa9, 0x2a, 0x4e, 0xc8, 0x25, 0x43, + 0xf4, 0x71, 0x0b, 0xc6, 0xf8, 0xef, 0x4b, 0x9d, 0x3a, 0x4f, 0xd9, 0xab, 0xe4, 0x11, 0x05, 0x5f, + 0x4d, 0xd0, 0x9c, 0x45, 0xb7, 0x77, 0x27, 0xc7, 0x92, 0x6d, 0x38, 0xc5, 0xd7, 0xfe, 0xca, 0x08, + 0x74, 0x87, 0x14, 0x24, 0xe3, 0x07, 0xac, 0xe3, 0x8e, 0x1f, 0xa0, 0xbb, 0xb4, 0x48, 0x1f, 0xfd, + 0xe7, 0xb0, 0xcc, 0x04, 0x57, 0x7d, 0xac, 0xdb, 0xf1, 0x6b, 0x98, 0xf1, 0x40, 0x21, 0x0c, 0x6e, + 0x12, 0xc7, 0x8b, 0x37, 0xf3, 0x39, 0x81, 0xba, 0xc4, 0x68, 0xa5, 0xf3, 0xef, 0x78, 0x2b, 0x16, + 0x9c, 0xd0, 0x0e, 0x0c, 0x6d, 0xf2, 0xb9, 0x28, 0x36, 0x4e, 0xcb, 0x87, 0x1d, 0xdc, 0xc4, 0x04, + 0xd7, 0x33, 0x4f, 0x34, 0x60, 0xc9, 0x8e, 0xc5, 0xaa, 0x19, 0xd1, 0x34, 0x5c, 0x8a, 0xe4, 0x97, + 0x7a, 0xd8, 0x7f, 0x28, 0xcd, 0xfb, 0x60, 0x24, 0x24, 0xb5, 0xc0, 0xaf, 0xb9, 0x1e, 0xa9, 0xcf, + 0xc8, 0xd3, 0xa5, 0x83, 0x64, 0x9c, 0x31, 0xd7, 0x0c, 0x36, 0x68, 0xe0, 0x04, 0x45, 0xb6, 0xc8, + 0x54, 0x16, 0x3a, 0xfd, 0x20, 0x44, 0x9c, 0x22, 0x2c, 0xe5, 0x94, 0xf3, 0xce, 0x68, 0xf2, 0x45, + 0x96, 0x6c, 0xc3, 0x29, 0xbe, 0xe8, 0x25, 0x80, 0x60, 0x9d, 0x07, 0xa4, 0xcd, 0xc4, 0xe2, 0x48, + 0xe1, 0x20, 0xaf, 0x3a, 0xc6, 0x33, 0x57, 0x25, 0x05, 0x6c, 0x50, 0x43, 0x57, 0x00, 0xf8, 0xb2, + 0x59, 0xeb, 0xb4, 0xe4, 0xee, 0x4a, 0xa6, 0x0c, 0x42, 0x55, 0x41, 0xee, 0xec, 0x4e, 0x76, 0x3b, + 0x70, 0x59, 0xd4, 0x8d, 0xf1, 0x38, 0xfa, 0x29, 0x18, 0x8a, 0xda, 0xcd, 0xa6, 0xa3, 0x0e, 0x1c, + 0x72, 0xcc, 0x85, 0xe5, 0x74, 0x0d, 0xa9, 0xc8, 0x1b, 0xb0, 0xe4, 0x88, 0x6e, 0x52, 0xf9, 0x2e, + 0xc4, 0x13, 0x5f, 0x45, 0xdc, 0x3c, 0xe1, 0x6e, 0xb5, 0xb7, 0xc9, 0xdd, 0x06, 0xce, 0xc0, 0xb9, + 0xb3, 0x3b, 0xf9, 0x40, 0xb2, 0x7d, 0x29, 0x10, 0xd9, 0xa9, 0x99, 0x34, 0xd1, 0x65, 0x59, 0x94, + 0x8a, 0xbe, 0xb6, 0xac, 0x95, 0xf2, 0xa4, 0x2e, 0x4a, 0xc5, 0x9a, 0x7b, 0x8f, 0x99, 0xf9, 0x30, + 0x5a, 0x86, 0x53, 0xb5, 0xc0, 0x8f, 0xc3, 0xc0, 0xf3, 0x78, 0x51, 0x36, 0xbe, 0xd1, 0xe5, 0x07, + 0x12, 0x0f, 0x8b, 0x6e, 0x9f, 0x9a, 0xeb, 0x46, 0xc1, 0x59, 0xcf, 0x51, 0x83, 0x3c, 0xad, 0x1c, + 0xc6, 0x72, 0x39, 0xab, 0x4e, 0xd0, 0x14, 0x12, 0x4a, 0xf9, 0x90, 0xf7, 0x51, 0x13, 0x7e, 0xf2, + 0xc4, 0x52, 0x7c, 0xb1, 0x67, 0x61, 0x84, 0xec, 0xc4, 0x24, 0xf4, 0x1d, 0xef, 0x1a, 0x5e, 0x92, + 0xde, 0x7f, 0xb6, 0x30, 0x2f, 0x18, 0xed, 0x38, 0x81, 0x85, 0x6c, 0xe5, 0x72, 0x32, 0xd2, 0xc0, + 0xb9, 0xcb, 0x49, 0x3a, 0x98, 0xec, 0xaf, 0x15, 0x13, 0x06, 0xeb, 0x3d, 0x39, 0x1f, 0x65, 0xf5, + 0x86, 0x64, 0x61, 0x26, 0x06, 0x10, 0x1b, 0xb1, 0x3c, 0x39, 0xab, 0x7a, 0x43, 0x2b, 0x26, 0x23, + 0x9c, 0xe4, 0x8b, 0xb6, 0xa0, 0xb4, 0x19, 0x44, 0xb1, 0xdc, 0x9e, 0x1d, 0x72, 0x27, 0x78, 0x29, + 0x88, 0x62, 0x66, 0x65, 0xa9, 0xd7, 0xa6, 0x2d, 0x11, 0xe6, 0x3c, 0xe8, 0x1e, 0x3d, 0xda, 0x74, + 0xc2, 0x7a, 0x34, 0xc7, 0x8a, 0x36, 0x0c, 0x30, 0xf3, 0x4a, 0x19, 0xd3, 0x55, 0x0d, 0xc2, 0x26, + 0x9e, 0xfd, 0x17, 0x56, 0xe2, 0x88, 0xe8, 0x06, 0x8b, 0xc0, 0xdf, 0x26, 0x3e, 0x15, 0x51, 0x66, + 0xcc, 0xdf, 0x8f, 0xa6, 0xf2, 0x99, 0xdf, 0xd2, 0xab, 0x7e, 0xe2, 0x2d, 0x4a, 0x61, 0x8a, 0x91, + 0x30, 0xc2, 0x03, 0x3f, 0x64, 0x25, 0x13, 0xd3, 0x0b, 0x79, 0xec, 0xdb, 0xcc, 0xe2, 0x0c, 0xfb, + 0xe6, 0xb8, 0xdb, 0x9f, 0xb3, 0x60, 0x68, 0xd6, 0xa9, 0x6d, 0x05, 0x1b, 0x1b, 0xe8, 0x29, 0x28, + 0xd7, 0xdb, 0xa1, 0x99, 0x23, 0xaf, 0x3c, 0x3f, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0x3a, 0xf5, 0x37, + 0x9c, 0x9a, 0x2c, 0xd1, 0x50, 0xe4, 0x53, 0xff, 0x22, 0x6b, 0xc1, 0x02, 0x42, 0x87, 0xbf, 0xe9, + 0xec, 0xc8, 0x87, 0xd3, 0xe7, 0x53, 0xcb, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0xdf, 0x58, 0x30, 0x31, + 0xeb, 0x44, 0x6e, 0x6d, 0xa6, 0x1d, 0x6f, 0xce, 0xba, 0xf1, 0x7a, 0xbb, 0xb6, 0x45, 0x62, 0x5e, + 0xca, 0x83, 0xf6, 0xb2, 0x1d, 0xd1, 0x15, 0xa8, 0xb6, 0xcb, 0xaa, 0x97, 0xd7, 0x44, 0x3b, 0x56, + 0x18, 0xe8, 0x35, 0x18, 0x6e, 0x39, 0x51, 0x74, 0x2b, 0x08, 0xeb, 0x98, 0x6c, 0xe4, 0x53, 0xec, + 0xa7, 0x4a, 0x6a, 0x21, 0x89, 0x31, 0xd9, 0x10, 0xd1, 0x1e, 0x9a, 0x3e, 0x36, 0x99, 0xd9, 0x3f, + 0x6f, 0xc1, 0xe9, 0x59, 0xe2, 0x84, 0x24, 0x64, 0xb5, 0x81, 0xd4, 0x8b, 0xa0, 0x57, 0xa1, 0x1c, + 0xd3, 0x16, 0xda, 0x23, 0x2b, 0xdf, 0x1e, 0xb1, 0x38, 0x8d, 0x35, 0x41, 0x1c, 0x2b, 0x36, 0xf6, + 0xa7, 0x2d, 0x78, 0x28, 0xab, 0x2f, 0x73, 0x5e, 0xd0, 0xae, 0xdf, 0x8b, 0x0e, 0xfd, 0x7d, 0x0b, + 0x46, 0xd8, 0xd9, 0xf7, 0x3c, 0x89, 0x1d, 0xd7, 0xeb, 0xaa, 0x4b, 0x68, 0xf5, 0x59, 0x97, 0xf0, + 0x1c, 0x0c, 0x6c, 0x06, 0x4d, 0x92, 0x8e, 0xdb, 0xb8, 0x14, 0x34, 0x09, 0x66, 0x10, 0xf4, 0x0c, + 0x9d, 0x84, 0xae, 0x1f, 0x3b, 0x74, 0x39, 0xca, 0xb3, 0x81, 0x71, 0x3e, 0x01, 0x55, 0x33, 0x36, + 0x71, 0xec, 0x7f, 0x5d, 0x81, 0x21, 0x11, 0x64, 0xd4, 0x77, 0x69, 0x19, 0xe9, 0xc2, 0x29, 0xf4, + 0x74, 0xe1, 0x44, 0x30, 0x58, 0x63, 0x05, 0x52, 0x85, 0x79, 0x7e, 0x25, 0x97, 0xa8, 0x34, 0x5e, + 0x73, 0x55, 0x77, 0x8b, 0xff, 0xc7, 0x82, 0x15, 0xfa, 0xac, 0x05, 0xe3, 0xb5, 0xc0, 0xf7, 0x49, + 0x4d, 0xdb, 0x8e, 0x03, 0x79, 0x04, 0x1f, 0xcd, 0x25, 0x89, 0xea, 0x63, 0xd5, 0x14, 0x00, 0xa7, + 0xd9, 0xa3, 0x17, 0x60, 0x94, 0x8f, 0xd9, 0xf5, 0xc4, 0x81, 0x86, 0x2e, 0x57, 0x67, 0x02, 0x71, + 0x12, 0x17, 0x4d, 0xf1, 0x83, 0x21, 0x51, 0x18, 0x6e, 0x50, 0xfb, 0x7d, 0x8d, 0x92, 0x70, 0x06, + 0x06, 0x0a, 0x01, 0x85, 0x64, 0x23, 0x24, 0xd1, 0xa6, 0x08, 0xc2, 0x62, 0x76, 0xeb, 0xd0, 0xdd, + 0x15, 0x85, 0xc0, 0x5d, 0x94, 0x70, 0x06, 0x75, 0xb4, 0x25, 0x7c, 0x08, 0xe5, 0x3c, 0xe4, 0xb9, + 0xf8, 0xcc, 0x3d, 0x5d, 0x09, 0x93, 0x50, 0x62, 0xaa, 0x8b, 0xd9, 0xcb, 0x45, 0x9e, 0x88, 0xc8, + 0x14, 0x1b, 0xe6, 0xed, 0x68, 0x1e, 0x4e, 0xa4, 0x8a, 0xed, 0x45, 0xe2, 0xe0, 0x41, 0x25, 0x9d, + 0xa5, 0xca, 0xf4, 0x45, 0xb8, 0xeb, 0x09, 0xd3, 0xbf, 0x34, 0xbc, 0x8f, 0x7f, 0xa9, 0xa3, 0x42, + 0x7d, 0xf9, 0x91, 0xc0, 0x8b, 0xb9, 0x0c, 0x40, 0x5f, 0x71, 0xbd, 0x9f, 0x4a, 0xc5, 0xf5, 0x8e, + 0xb2, 0x0e, 0x5c, 0xcf, 0xa7, 0x03, 0x07, 0x0f, 0xe2, 0xbd, 0x97, 0x41, 0xb9, 0xff, 0xcb, 0x02, + 0xf9, 0x5d, 0xe7, 0x9c, 0xda, 0x26, 0xa1, 0x53, 0x06, 0xbd, 0x03, 0xc6, 0x94, 0x6b, 0x82, 0x9b, + 0x44, 0x16, 0x9b, 0x35, 0xca, 0x76, 0xc6, 0x09, 0x28, 0x4e, 0x61, 0xa3, 0x69, 0xa8, 0xd0, 0x71, + 0xe2, 0x8f, 0x72, 0xbd, 0xaf, 0xdc, 0x1f, 0x33, 0xab, 0x8b, 0xe2, 0x29, 0x8d, 0x83, 0x02, 0x38, + 0xe9, 0x39, 0x51, 0xcc, 0x7a, 0x50, 0xed, 0xf8, 0xb5, 0xbb, 0x2c, 0xc9, 0xc2, 0x32, 0x9b, 0x96, + 0xd2, 0x84, 0x70, 0x37, 0x6d, 0xfb, 0x3f, 0x96, 0x60, 0x34, 0x21, 0x19, 0x0f, 0x68, 0x30, 0x3c, + 0x05, 0x65, 0xa9, 0xc3, 0xd3, 0xb5, 0xa7, 0x94, 0xa2, 0x57, 0x18, 0x54, 0x69, 0xad, 0x6b, 0xad, + 0x9a, 0x36, 0x70, 0x0c, 0x85, 0x8b, 0x4d, 0x3c, 0x26, 0x94, 0x63, 0x2f, 0x9a, 0xf3, 0x5c, 0xe2, + 0xc7, 0xbc, 0x9b, 0xf9, 0x08, 0xe5, 0xb5, 0xa5, 0xaa, 0x49, 0x54, 0x0b, 0xe5, 0x14, 0x00, 0xa7, + 0xd9, 0xa3, 0x8f, 0x5a, 0x30, 0xea, 0xdc, 0x8a, 0x74, 0x15, 0x6f, 0x11, 0xc1, 0x7b, 0x48, 0x25, + 0x95, 0x28, 0x0c, 0xce, 0xbd, 0xfa, 0x89, 0x26, 0x9c, 0x64, 0x8a, 0x5e, 0xb7, 0x00, 0x91, 0x1d, + 0x52, 0x93, 0x31, 0xc6, 0xa2, 0x2f, 0x83, 0x79, 0xec, 0xe0, 0x2f, 0x74, 0xd1, 0xe5, 0x52, 0xbd, + 0xbb, 0x1d, 0x67, 0xf4, 0x01, 0x5d, 0x06, 0x54, 0x77, 0x23, 0x67, 0xdd, 0x23, 0x73, 0x41, 0x53, + 0x66, 0xe3, 0x8a, 0xc3, 0xe9, 0xb3, 0x62, 0x9c, 0xd1, 0x7c, 0x17, 0x06, 0xce, 0x78, 0x8a, 0xcd, + 0xb2, 0x30, 0xd8, 0xe9, 0x5c, 0x0b, 0x3d, 0xa6, 0x25, 0xcc, 0x59, 0x26, 0xda, 0xb1, 0xc2, 0xb0, + 0xff, 0xb2, 0xa8, 0x96, 0xb2, 0x0e, 0xa8, 0x77, 0x8c, 0xc0, 0x5e, 0xeb, 0xee, 0x03, 0x7b, 0x75, + 0xd8, 0x51, 0x77, 0x8e, 0x79, 0x22, 0x25, 0xb5, 0x70, 0x8f, 0x52, 0x52, 0x7f, 0xc6, 0x4a, 0xd4, + 0x77, 0x1b, 0x3e, 0xff, 0x52, 0xbe, 0xc1, 0xfc, 0x53, 0x3c, 0x24, 0x2a, 0xa5, 0x57, 0x52, 0x91, + 0x70, 0x4f, 0x41, 0x79, 0xc3, 0x73, 0x58, 0x55, 0x12, 0xb6, 0x50, 0x8d, 0x70, 0xad, 0x8b, 0xa2, + 0x1d, 0x2b, 0x0c, 0x2a, 0xf5, 0x0d, 0xa2, 0x07, 0x92, 0xda, 0xff, 0xb9, 0x08, 0xc3, 0x86, 0xc6, + 0xcf, 0x34, 0xdf, 0xac, 0xfb, 0xcc, 0x7c, 0x2b, 0x1c, 0xc0, 0x7c, 0xfb, 0x69, 0xa8, 0xd4, 0xa4, + 0x36, 0xca, 0xa7, 0x5e, 0x7d, 0x5a, 0xc7, 0x69, 0x85, 0xa4, 0x9a, 0xb0, 0xe6, 0x89, 0x16, 0x12, + 0x69, 0x8f, 0x09, 0xbf, 0x40, 0x56, 0x5e, 0xa2, 0xd0, 0x68, 0xdd, 0xcf, 0xa4, 0xcf, 0xf1, 0x4b, + 0xfb, 0x9f, 0xe3, 0xdb, 0xdf, 0xb2, 0xd4, 0xc7, 0x3d, 0x86, 0xfa, 0x36, 0x37, 0x93, 0xf5, 0x6d, + 0x2e, 0xe4, 0x32, 0xcc, 0x3d, 0x0a, 0xdb, 0x5c, 0x85, 0xa1, 0xb9, 0xa0, 0xd9, 0x74, 0xfc, 0x3a, + 0xfa, 0x41, 0x18, 0xaa, 0xf1, 0x9f, 0xc2, 0x87, 0xc6, 0x4e, 0xaa, 0x05, 0x14, 0x4b, 0x18, 0x7a, + 0x04, 0x06, 0x9c, 0xb0, 0x21, 0xfd, 0x66, 0x2c, 0xa2, 0x6c, 0x26, 0x6c, 0x44, 0x98, 0xb5, 0xda, + 0xff, 0x62, 0x00, 0x58, 0x20, 0x87, 0x13, 0x92, 0xfa, 0x5a, 0xc0, 0xca, 0xcc, 0x1e, 0xe9, 0xf9, + 0xae, 0xde, 0xd4, 0xdd, 0xcf, 0x67, 0xbc, 0xc6, 0x39, 0x5f, 0xf1, 0xb8, 0xcf, 0xf9, 0xb2, 0x8f, + 0x6e, 0x07, 0xee, 0xa3, 0xa3, 0x5b, 0xfb, 0x93, 0x16, 0x20, 0x15, 0xfd, 0xa3, 0x63, 0x2b, 0xa6, + 0xa1, 0xa2, 0xe2, 0x80, 0x84, 0x01, 0xa8, 0x45, 0x84, 0x04, 0x60, 0x8d, 0xd3, 0xc7, 0x4e, 0xfe, + 0x71, 0x29, 0xbf, 0x8b, 0xc9, 0x60, 0x7e, 0x26, 0xf5, 0x85, 0x38, 0xb7, 0x7f, 0xb7, 0x00, 0x0f, + 0x70, 0xd3, 0x61, 0xd9, 0xf1, 0x9d, 0x06, 0x69, 0xd2, 0x5e, 0xf5, 0x1b, 0x2d, 0x53, 0xa3, 0x5b, + 0x48, 0x57, 0x86, 0xde, 0x1f, 0x76, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xa2, 0xef, 0xc6, 0x98, + 0x11, 0x47, 0x11, 0x94, 0xe5, 0x65, 0x2e, 0x42, 0x16, 0xe7, 0xc4, 0x48, 0x89, 0x25, 0xa1, 0x65, + 0x09, 0x56, 0x8c, 0xa8, 0x2a, 0xf5, 0x82, 0xda, 0x16, 0x26, 0xad, 0x20, 0xad, 0x4a, 0x97, 0x44, + 0x3b, 0x56, 0x18, 0x76, 0x13, 0xc6, 0xe5, 0x18, 0xb6, 0xae, 0x90, 0x0e, 0x26, 0x1b, 0x54, 0xff, + 0xd4, 0x64, 0x93, 0x71, 0xbf, 0x8c, 0xd2, 0x3f, 0x73, 0x26, 0x10, 0x27, 0x71, 0x65, 0xe5, 0xd9, + 0x42, 0x76, 0xe5, 0x59, 0xfb, 0x77, 0x2d, 0x48, 0x2b, 0x40, 0xa3, 0xce, 0xa6, 0xb5, 0x67, 0x9d, + 0xcd, 0x03, 0x54, 0xaa, 0xfc, 0x49, 0x18, 0x76, 0x62, 0x6a, 0xe1, 0x70, 0x6f, 0x44, 0xf1, 0xee, + 0x4e, 0xd1, 0x96, 0x83, 0xba, 0xbb, 0xe1, 0x32, 0x2f, 0x84, 0x49, 0xce, 0x7e, 0xdd, 0x82, 0xca, + 0x7c, 0xd8, 0x39, 0x78, 0x0e, 0x54, 0x77, 0x86, 0x53, 0xe1, 0x40, 0x19, 0x4e, 0x32, 0x87, 0xaa, + 0xd8, 0x2b, 0x87, 0xca, 0xfe, 0xeb, 0x01, 0x38, 0xd9, 0x95, 0xd4, 0x87, 0x9e, 0x87, 0x11, 0xf5, + 0x95, 0xa4, 0x0b, 0xb2, 0x62, 0x46, 0xc5, 0x6a, 0x18, 0x4e, 0x60, 0xf6, 0xb1, 0x54, 0x17, 0xe1, + 0x54, 0x48, 0x5e, 0x6d, 0x93, 0x36, 0x99, 0xd9, 0x88, 0x49, 0x58, 0x25, 0xb5, 0xc0, 0xaf, 0xf3, + 0x42, 0xb5, 0xc5, 0xd9, 0x07, 0x6f, 0xef, 0x4e, 0x9e, 0xc2, 0xdd, 0x60, 0x9c, 0xf5, 0x0c, 0x6a, + 0xc1, 0xa8, 0x67, 0xda, 0xce, 0x62, 0xcb, 0x76, 0x57, 0x66, 0xb7, 0x9a, 0xad, 0x89, 0x66, 0x9c, + 0x64, 0x90, 0x34, 0xc0, 0x4b, 0xf7, 0xc8, 0x00, 0xff, 0x88, 0x36, 0xc0, 0x79, 0x50, 0xcc, 0x7b, + 0x72, 0x4e, 0xea, 0xec, 0xc7, 0x02, 0x3f, 0x8c, 0x4d, 0xfd, 0x22, 0x94, 0x65, 0xc0, 0x60, 0x5f, + 0x81, 0x76, 0x26, 0x9d, 0x1e, 0xb2, 0xfd, 0x09, 0x78, 0xf3, 0x85, 0x30, 0x34, 0x06, 0xf3, 0x6a, + 0x10, 0xcf, 0x78, 0x5e, 0x70, 0x8b, 0x9a, 0x2b, 0xd7, 0x22, 0x22, 0x7c, 0x62, 0xf6, 0x9d, 0x02, + 0x64, 0x6c, 0x2f, 0xe9, 0x9a, 0xd4, 0x36, 0x52, 0x62, 0x4d, 0x1e, 0xcc, 0x4e, 0x42, 0x3b, 0x3c, + 0xa8, 0x92, 0x5b, 0x03, 0xef, 0xce, 0x7b, 0x7b, 0xac, 0xe3, 0x2c, 0x95, 0xa4, 0x54, 0xb1, 0x96, + 0xe7, 0x01, 0xb4, 0x69, 0x2b, 0xf2, 0x88, 0x54, 0xa0, 0x84, 0xb6, 0x80, 0xb1, 0x81, 0x85, 0x9e, + 0x83, 0x61, 0xd7, 0x8f, 0x62, 0xc7, 0xf3, 0x2e, 0xb9, 0x7e, 0x2c, 0xdc, 0xbe, 0xca, 0xec, 0x59, + 0xd4, 0x20, 0x6c, 0xe2, 0x9d, 0x7d, 0x9b, 0xf1, 0xfd, 0x0e, 0xf2, 0xdd, 0x37, 0xe1, 0xa1, 0x05, + 0x37, 0x56, 0xd9, 0x6f, 0x6a, 0xbe, 0x51, 0xcb, 0x55, 0xc9, 0x2a, 0xab, 0x67, 0xbe, 0xa7, 0x91, + 0x7d, 0x56, 0x48, 0x26, 0xcb, 0xa5, 0xb3, 0xcf, 0xec, 0xe7, 0xe1, 0xf4, 0x82, 0x1b, 0x5f, 0x74, + 0x3d, 0x72, 0x40, 0x26, 0xf6, 0xef, 0x0c, 0xc2, 0x88, 0x99, 0xe9, 0x7d, 0x10, 0x71, 0xfd, 0x69, + 0x6a, 0x9c, 0x8a, 0xb7, 0x73, 0xd5, 0x89, 0xee, 0x8d, 0x43, 0xa7, 0x9d, 0x67, 0x8f, 0x98, 0x61, + 0x9f, 0x6a, 0x9e, 0xd8, 0xec, 0x00, 0xba, 0x05, 0xa5, 0x0d, 0x96, 0x1d, 0x55, 0xcc, 0x23, 0x16, + 0x27, 0x6b, 0x44, 0xf5, 0x72, 0xe4, 0xf9, 0x55, 0x9c, 0x1f, 0xb5, 0x29, 0xc2, 0x64, 0x52, 0xae, + 0x11, 0xb3, 0x2e, 0x94, 0x95, 0xc2, 0xe8, 0xa5, 0x12, 0x4a, 0x77, 0xa1, 0x12, 0x12, 0x02, 0x7a, + 0xf0, 0x1e, 0x09, 0x68, 0x96, 0xe9, 0x16, 0x6f, 0x32, 0x8b, 0x57, 0x24, 0xd9, 0x0c, 0xb1, 0x41, + 0x30, 0x32, 0xdd, 0x12, 0x60, 0x9c, 0xc6, 0x47, 0x1f, 0x54, 0x22, 0xbe, 0x9c, 0x87, 0xc7, 0xdc, + 0x9c, 0xd1, 0x47, 0x2d, 0xdd, 0x3f, 0x59, 0x80, 0xb1, 0x05, 0xbf, 0xbd, 0xba, 0xb0, 0xda, 0x5e, + 0xf7, 0xdc, 0xda, 0x15, 0xd2, 0xa1, 0x22, 0x7c, 0x8b, 0x74, 0x16, 0xe7, 0xc5, 0x0a, 0x52, 0x73, + 0xe6, 0x0a, 0x6d, 0xc4, 0x1c, 0x46, 0x85, 0xd1, 0x86, 0xeb, 0x37, 0x48, 0xd8, 0x0a, 0x5d, 0xe1, + 0xcc, 0x36, 0x84, 0xd1, 0x45, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf2, 0x49, 0x98, 0x36, + 0xfd, 0x57, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x14, 0x87, 0x6d, 0xe1, 0x2b, 0x32, 0x90, 0xd6, 0x68, + 0x23, 0xe6, 0x30, 0xba, 0xd2, 0xa3, 0xf6, 0x3a, 0x0b, 0x75, 0x4a, 0x65, 0xf4, 0x54, 0x79, 0x33, + 0x96, 0x70, 0x8a, 0xba, 0x45, 0x3a, 0xf3, 0x4e, 0xec, 0xa4, 0xd3, 0x1e, 0xaf, 0xf0, 0x66, 0x2c, + 0xe1, 0xac, 0x94, 0x6e, 0x72, 0x38, 0xbe, 0xe7, 0x4a, 0xe9, 0x26, 0xbb, 0xdf, 0xc3, 0xe3, 0xf0, + 0xf7, 0x0a, 0x30, 0x62, 0x06, 0x28, 0xa2, 0x46, 0xca, 0x4c, 0x5f, 0xe9, 0xaa, 0xc4, 0xfe, 0xf6, + 0xac, 0x5b, 0x4a, 0x1b, 0x6e, 0x1c, 0xb4, 0xa2, 0xa7, 0x89, 0xdf, 0x70, 0x7d, 0xc2, 0x62, 0x35, + 0x78, 0x60, 0x63, 0x22, 0xfa, 0x71, 0x2e, 0xa8, 0x93, 0xbb, 0xb1, 0xf3, 0xef, 0xc5, 0x4d, 0x2e, + 0x37, 0xe0, 0x64, 0x57, 0x7e, 0x6d, 0x1f, 0x66, 0xcf, 0xbe, 0xf5, 0x0f, 0x6c, 0x0c, 0xc3, 0x94, + 0xb0, 0x2c, 0x21, 0x37, 0x07, 0x27, 0xf9, 0xe2, 0xa5, 0x9c, 0x58, 0xba, 0xa4, 0xca, 0x99, 0x66, + 0xa7, 0x35, 0xd7, 0xd3, 0x40, 0xdc, 0x8d, 0x6f, 0x7f, 0xca, 0x82, 0xd1, 0x44, 0xca, 0x73, 0x4e, + 0x06, 0x1a, 0x5b, 0xdd, 0x01, 0x8b, 0xd1, 0x65, 0x39, 0x13, 0x45, 0xa6, 0xc0, 0xf5, 0xea, 0xd6, + 0x20, 0x6c, 0xe2, 0xd9, 0x9f, 0x2b, 0x40, 0x59, 0x86, 0x14, 0xf5, 0xd1, 0x95, 0x4f, 0x58, 0x30, + 0xaa, 0x4e, 0xc8, 0x98, 0x4b, 0xb3, 0x90, 0x47, 0x06, 0x16, 0xed, 0x81, 0x72, 0x8a, 0xf8, 0x1b, + 0x81, 0xde, 0x2d, 0x60, 0x93, 0x19, 0x4e, 0xf2, 0x46, 0xd7, 0x01, 0xa2, 0x4e, 0x14, 0x93, 0xa6, + 0xe1, 0x5c, 0xb5, 0x8d, 0x59, 0x36, 0x55, 0x0b, 0x42, 0x42, 0xe7, 0xd4, 0xd5, 0xa0, 0x4e, 0xaa, + 0x0a, 0x53, 0x9b, 0x6d, 0xba, 0x0d, 0x1b, 0x94, 0xec, 0x5f, 0x2b, 0xc0, 0x89, 0x74, 0x97, 0xd0, + 0x7b, 0x60, 0x44, 0x72, 0x37, 0x36, 0xe1, 0x32, 0x20, 0x6a, 0x04, 0x1b, 0xb0, 0x3b, 0xbb, 0x93, + 0x93, 0xdd, 0xb7, 0xec, 0x4e, 0x99, 0x28, 0x38, 0x41, 0x8c, 0x1f, 0x53, 0x8a, 0xf3, 0xf4, 0xd9, + 0xce, 0x4c, 0xab, 0x25, 0xce, 0x1a, 0x8d, 0x63, 0x4a, 0x13, 0x8a, 0x53, 0xd8, 0x68, 0x15, 0x4e, + 0x1b, 0x2d, 0x57, 0x89, 0xdb, 0xd8, 0x5c, 0x0f, 0x42, 0xb9, 0xeb, 0x7b, 0x44, 0x87, 0x5f, 0x76, + 0xe3, 0xe0, 0xcc, 0x27, 0xa9, 0x85, 0x51, 0x73, 0x5a, 0x4e, 0xcd, 0x8d, 0x3b, 0xc2, 0x5b, 0xac, + 0xe4, 0xe1, 0x9c, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0xd5, 0x01, 0x38, 0xc1, 0xe3, 0x0d, 0x89, 0x0a, + 0xa7, 0x45, 0xef, 0x81, 0x4a, 0x14, 0x3b, 0x21, 0xdf, 0xf2, 0x5b, 0x07, 0x96, 0x01, 0x3a, 0xe1, + 0x59, 0x12, 0xc1, 0x9a, 0x1e, 0x7a, 0x89, 0x55, 0x8b, 0x72, 0xa3, 0x4d, 0x46, 0xbd, 0x70, 0x77, + 0x0e, 0x85, 0x8b, 0x8a, 0x02, 0x36, 0xa8, 0xa1, 0x1f, 0x87, 0x52, 0x6b, 0xd3, 0x89, 0xa4, 0xb7, + 0xeb, 0x09, 0xb9, 0xe0, 0x56, 0x69, 0xe3, 0x9d, 0xdd, 0xc9, 0x33, 0xe9, 0x57, 0x65, 0x00, 0xcc, + 0x1f, 0x32, 0xc5, 0xe5, 0xc0, 0xfe, 0x37, 0x9a, 0xd4, 0xc3, 0x4e, 0xf5, 0xd2, 0x4c, 0xfa, 0x0e, + 0x8c, 0x79, 0xd6, 0x8a, 0x05, 0x94, 0x2e, 0xee, 0x4d, 0xce, 0xb2, 0x4e, 0x91, 0x07, 0x93, 0xaa, + 0xfb, 0x92, 0x06, 0x61, 0x13, 0x0f, 0x7d, 0xb2, 0x3b, 0x1a, 0x75, 0xe8, 0x08, 0x52, 0x15, 0xfa, + 0x8d, 0x43, 0xbd, 0x00, 0x15, 0xd1, 0xd5, 0xb5, 0x00, 0x3d, 0x0f, 0x23, 0xdc, 0x99, 0x32, 0x1b, + 0x3a, 0x7e, 0x6d, 0x33, 0xed, 0x02, 0x59, 0x33, 0x60, 0x38, 0x81, 0x69, 0x2f, 0xc3, 0x40, 0x9f, + 0xd2, 0xaa, 0xaf, 0x9d, 0xed, 0x8b, 0x50, 0xa6, 0xe4, 0xe4, 0xf6, 0x25, 0x0f, 0x92, 0x01, 0x94, + 0xe5, 0xfd, 0x78, 0xc8, 0x86, 0xa2, 0xeb, 0xc8, 0xa8, 0x03, 0xb5, 0x84, 0x16, 0xa3, 0xa8, 0xcd, + 0xa6, 0x1d, 0x05, 0xa2, 0xc7, 0xa1, 0x48, 0x76, 0x5a, 0xe9, 0xf0, 0x82, 0x0b, 0x3b, 0x2d, 0x37, + 0x24, 0x11, 0x45, 0x22, 0x3b, 0x2d, 0x74, 0x16, 0x0a, 0x6e, 0x5d, 0xcc, 0x48, 0x10, 0x38, 0x85, + 0xc5, 0x79, 0x5c, 0x70, 0xeb, 0xf6, 0x0e, 0x54, 0xd4, 0x85, 0x7c, 0x68, 0x4b, 0xda, 0x26, 0x56, + 0x1e, 0xf1, 0xa6, 0x92, 0x6e, 0x0f, 0xab, 0xa4, 0x0d, 0xa0, 0x33, 0xe9, 0xf3, 0xd2, 0x65, 0xe7, + 0x60, 0xa0, 0x16, 0x88, 0x1a, 0x28, 0x65, 0x4d, 0x86, 0x19, 0x25, 0x0c, 0x62, 0xdf, 0x80, 0xb1, + 0x2b, 0x7e, 0x70, 0x8b, 0xdd, 0x9b, 0xc3, 0xca, 0xc4, 0x52, 0xc2, 0x1b, 0xf4, 0x47, 0xda, 0x04, + 0x66, 0x50, 0xcc, 0x61, 0xaa, 0x80, 0x65, 0xa1, 0x57, 0x01, 0x4b, 0xfb, 0x43, 0x16, 0x8c, 0xa8, + 0x94, 0xdc, 0x85, 0xed, 0x2d, 0x4a, 0xb7, 0x11, 0x06, 0xed, 0x56, 0x9a, 0x2e, 0xbb, 0xfb, 0x13, + 0x73, 0x98, 0x99, 0xab, 0x5e, 0xd8, 0x27, 0x57, 0xfd, 0x1c, 0x0c, 0x6c, 0xb9, 0x7e, 0x3d, 0xed, + 0x32, 0xbc, 0xe2, 0xfa, 0x75, 0xcc, 0x20, 0xb4, 0x0b, 0x27, 0x54, 0x17, 0xa4, 0xf1, 0xf1, 0x3c, + 0x8c, 0xac, 0xb7, 0x5d, 0xaf, 0x2e, 0xeb, 0xdf, 0xa6, 0x96, 0xcb, 0xac, 0x01, 0xc3, 0x09, 0x4c, + 0x74, 0x1e, 0x60, 0xdd, 0xf5, 0x9d, 0xb0, 0xb3, 0xaa, 0xad, 0x1d, 0xa5, 0x00, 0x67, 0x15, 0x04, + 0x1b, 0x58, 0xf6, 0x67, 0x8a, 0x30, 0x96, 0x4c, 0x4c, 0xee, 0xc3, 0x7d, 0xf0, 0x38, 0x94, 0x58, + 0xae, 0x72, 0xfa, 0xd3, 0xf2, 0x92, 0xb1, 0x1c, 0x86, 0x22, 0x18, 0xe4, 0x8b, 0x39, 0x9f, 0xfb, + 0x13, 0x55, 0x27, 0x95, 0x9f, 0x91, 0x45, 0xe5, 0x0a, 0xb7, 0xad, 0x60, 0x85, 0x3e, 0x6a, 0xc1, + 0x50, 0xd0, 0x32, 0x0b, 0x1f, 0xbe, 0x3b, 0xcf, 0xa4, 0x6d, 0x91, 0xc9, 0x29, 0x76, 0x7c, 0xea, + 0xd3, 0xcb, 0xcf, 0x21, 0x59, 0x9f, 0xfd, 0x31, 0x18, 0x31, 0x31, 0xf7, 0xdb, 0xf4, 0x95, 0xcd, + 0x4d, 0xdf, 0x27, 0xcc, 0x49, 0x21, 0xd2, 0xd2, 0xfb, 0x58, 0x6e, 0xd7, 0xa0, 0x54, 0x53, 0xa1, + 0x4b, 0x77, 0x55, 0x35, 0x5d, 0x95, 0x6d, 0x62, 0xc7, 0xc2, 0x9c, 0x9a, 0xfd, 0x2d, 0xcb, 0x98, + 0x1f, 0x98, 0x44, 0x8b, 0x75, 0x14, 0x42, 0xb1, 0xb1, 0xbd, 0x25, 0xd4, 0xfc, 0xe5, 0x9c, 0x86, + 0x77, 0x61, 0x7b, 0x4b, 0xcf, 0x71, 0xb3, 0x15, 0x53, 0x66, 0x7d, 0x38, 0xc3, 0x13, 0xd5, 0x0b, + 0x8a, 0xfb, 0x57, 0x2f, 0xb0, 0x5f, 0x2f, 0xc0, 0xc9, 0xae, 0x49, 0x85, 0x5e, 0x83, 0x52, 0x48, + 0xdf, 0x52, 0xbc, 0xde, 0x52, 0x6e, 0xf5, 0x06, 0xa2, 0xc5, 0xba, 0x56, 0x9f, 0xc9, 0x76, 0xcc, + 0x59, 0xa2, 0xcb, 0x80, 0x74, 0x80, 0x9d, 0xf2, 0xc4, 0xf3, 0x57, 0x56, 0x51, 0x38, 0x33, 0x5d, + 0x18, 0x38, 0xe3, 0x29, 0xf4, 0x42, 0xda, 0xa1, 0x5f, 0x4c, 0x9e, 0x24, 0xed, 0xe5, 0x9b, 0xb7, + 0x7f, 0xab, 0x00, 0xa3, 0x89, 0x3a, 0x94, 0xc8, 0x83, 0x32, 0xf1, 0xd8, 0x31, 0x9f, 0x54, 0x36, + 0x87, 0xbd, 0x55, 0x42, 0x29, 0xc8, 0x0b, 0x82, 0x2e, 0x56, 0x1c, 0xee, 0x8f, 0xe0, 0x9c, 0xe7, + 0x61, 0x44, 0x76, 0xe8, 0xdd, 0x4e, 0xd3, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x05, 0x03, 0x86, 0x13, + 0x98, 0xf6, 0xef, 0x15, 0x61, 0x82, 0x9f, 0x8b, 0xd6, 0xd5, 0xcc, 0x5b, 0x96, 0xfe, 0x84, 0x5f, + 0xd0, 0xd5, 0x62, 0xad, 0x3c, 0xae, 0x4e, 0xee, 0xc5, 0xa8, 0xaf, 0x98, 0xd2, 0x2f, 0xa6, 0x62, + 0x4a, 0xf9, 0x16, 0xaf, 0x71, 0x44, 0x3d, 0xfa, 0xde, 0x0a, 0x32, 0xfd, 0x27, 0x05, 0x18, 0x4f, + 0xdd, 0x90, 0x85, 0x3e, 0x93, 0xbc, 0x54, 0xc1, 0xca, 0xe3, 0xcc, 0x68, 0xcf, 0x4b, 0x93, 0x0e, + 0x76, 0xb5, 0xc2, 0x3d, 0x5a, 0x2a, 0xf6, 0x37, 0x0b, 0x30, 0x96, 0xbc, 0xda, 0xeb, 0x3e, 0x1c, + 0xa9, 0xb7, 0x42, 0x85, 0xdd, 0x5e, 0xc3, 0x6e, 0xa4, 0xe7, 0x47, 0x4e, 0xfc, 0xa2, 0x10, 0xd9, + 0x88, 0x35, 0xfc, 0xbe, 0xb8, 0xb1, 0xc2, 0xfe, 0x67, 0x16, 0x9c, 0xe1, 0x6f, 0x99, 0x9e, 0x87, + 0x7f, 0x27, 0x6b, 0x74, 0x5f, 0xce, 0xb7, 0x83, 0xa9, 0x2a, 0xc7, 0xfb, 0x8d, 0x2f, 0xbb, 0x40, + 0x5a, 0xf4, 0x36, 0x39, 0x15, 0xee, 0xc3, 0xce, 0x1e, 0x68, 0x32, 0xd8, 0xdf, 0x2c, 0x82, 0xbe, + 0x33, 0x1b, 0xb9, 0x22, 0xeb, 0x3d, 0x97, 0x6a, 0xcf, 0xd5, 0x8e, 0x5f, 0xd3, 0xb7, 0x73, 0x97, + 0x53, 0x49, 0xef, 0x3f, 0x67, 0xc1, 0xb0, 0xeb, 0xbb, 0xb1, 0xeb, 0x30, 0x97, 0x4d, 0x3e, 0x17, + 0xdf, 0x2a, 0x76, 0x8b, 0x9c, 0x72, 0x10, 0x9a, 0xe7, 0x94, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0xf7, + 0x89, 0xb4, 0x8f, 0x62, 0x6e, 0xa5, 0x23, 0xca, 0xa9, 0x5c, 0x8f, 0x16, 0x35, 0xbc, 0xe2, 0x30, + 0xa7, 0x8a, 0x2b, 0x98, 0x92, 0x52, 0x17, 0x07, 0x28, 0xd3, 0x96, 0x35, 0x63, 0xce, 0xc8, 0x8e, + 0x00, 0x75, 0x8f, 0xc5, 0x01, 0x43, 0xea, 0xa7, 0xa1, 0xe2, 0xb4, 0xe3, 0xa0, 0x49, 0x87, 0x49, + 0x1c, 0xa5, 0xea, 0xa4, 0x01, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x4c, 0x09, 0x52, 0x69, 0xe8, 0x68, + 0xc7, 0xbc, 0xef, 0xdd, 0xca, 0xf7, 0xbe, 0x77, 0xd5, 0x99, 0xac, 0x3b, 0xdf, 0x51, 0x43, 0x7a, + 0xbf, 0xb8, 0x8d, 0xf9, 0x62, 0xda, 0xfb, 0xf5, 0x13, 0xfd, 0x9d, 0x2a, 0xd0, 0xb9, 0x3a, 0xcd, + 0xab, 0x78, 0x4d, 0xed, 0xeb, 0x28, 0xdb, 0xef, 0xea, 0xdf, 0x0f, 0x8b, 0x6b, 0x7a, 0x30, 0x89, + 0xda, 0x5e, 0x2c, 0x66, 0xc3, 0x8b, 0x39, 0xae, 0x32, 0x4e, 0x58, 0xd7, 0x72, 0xe1, 0xff, 0xb1, + 0xc1, 0x34, 0xe9, 0xce, 0x1c, 0x3c, 0x52, 0x77, 0xe6, 0x50, 0xae, 0xee, 0xcc, 0xf3, 0x00, 0x6c, + 0x6e, 0xf3, 0xd0, 0xdf, 0x32, 0xf3, 0x32, 0x29, 0x51, 0x88, 0x15, 0x04, 0x1b, 0x58, 0xf6, 0x0f, + 0x43, 0xb2, 0x18, 0x11, 0x9a, 0x94, 0xb5, 0x8f, 0xf8, 0x89, 0x07, 0xcb, 0xba, 0x4a, 0x94, 0x29, + 0xfa, 0x0d, 0x0b, 0xcc, 0x8a, 0x49, 0xe8, 0x55, 0x5e, 0x9a, 0xc9, 0xca, 0xe3, 0x64, 0xdc, 0xa0, + 0x3b, 0xb5, 0xec, 0xb4, 0x52, 0x21, 0x1a, 0xb2, 0x3e, 0xd3, 0xd9, 0xb7, 0x41, 0x59, 0x42, 0x0f, + 0x64, 0xd4, 0x7d, 0x10, 0x4e, 0xc9, 0x0c, 0x6e, 0xe9, 0xa3, 0x17, 0xa7, 0xaa, 0xfb, 0xbb, 0x7e, + 0xa4, 0x3f, 0xa7, 0xd0, 0xcb, 0x9f, 0xd3, 0xc7, 0xad, 0xff, 0xbf, 0x69, 0xc1, 0xb9, 0x74, 0x07, + 0xa2, 0xe5, 0xc0, 0x77, 0xe3, 0x20, 0xac, 0x92, 0x38, 0x76, 0xfd, 0x06, 0xab, 0x48, 0x79, 0xcb, + 0x09, 0xe5, 0xad, 0x24, 0x4c, 0x50, 0xde, 0x70, 0x42, 0x1f, 0xb3, 0x56, 0xd4, 0x81, 0x41, 0x1e, + 0x1f, 0x2a, 0xac, 0xf5, 0x43, 0xae, 0x8d, 0x8c, 0xe1, 0xd0, 0xdb, 0x05, 0x1e, 0x9b, 0x8a, 0x05, + 0x43, 0xfb, 0x3b, 0x16, 0xa0, 0x95, 0x6d, 0x12, 0x86, 0x6e, 0xdd, 0x88, 0x68, 0x65, 0xd7, 0xdd, + 0x19, 0xd7, 0xda, 0x99, 0xf5, 0x05, 0x52, 0xd7, 0xdd, 0x19, 0xff, 0xb2, 0xaf, 0xbb, 0x2b, 0x1c, + 0xec, 0xba, 0x3b, 0xb4, 0x02, 0x67, 0x9a, 0x7c, 0xbb, 0xc1, 0xaf, 0x90, 0xe2, 0x7b, 0x0f, 0x95, + 0x0a, 0xfb, 0xd0, 0xed, 0xdd, 0xc9, 0x33, 0xcb, 0x59, 0x08, 0x38, 0xfb, 0x39, 0xfb, 0x6d, 0x80, + 0x78, 0x20, 0xeb, 0x5c, 0x56, 0x2c, 0x5e, 0x4f, 0xf7, 0x8b, 0xfd, 0x85, 0x12, 0x8c, 0xa7, 0x6a, + 0xd6, 0xd3, 0xad, 0x5e, 0x77, 0xf0, 0xdf, 0xa1, 0xf5, 0x77, 0x77, 0xf7, 0xfa, 0x0a, 0x27, 0xf4, + 0xa1, 0xe4, 0xfa, 0xad, 0x76, 0x9c, 0x4f, 0x26, 0x3e, 0xef, 0xc4, 0x22, 0x25, 0x68, 0xb8, 0x8b, + 0xe9, 0x5f, 0xcc, 0xd9, 0xe4, 0x19, 0x9c, 0x98, 0x30, 0xc6, 0x07, 0xee, 0x91, 0x3b, 0xe0, 0xc3, + 0x3a, 0x54, 0xb0, 0x94, 0x87, 0x63, 0x31, 0x35, 0x59, 0x8e, 0x3a, 0x94, 0xe4, 0x6b, 0x05, 0x18, + 0x36, 0x3e, 0x1a, 0xfa, 0x95, 0x64, 0x3d, 0x41, 0x2b, 0xbf, 0x57, 0x62, 0xf4, 0xa7, 0x74, 0xc5, + 0x40, 0xfe, 0x4a, 0x4f, 0x74, 0x97, 0x12, 0xbc, 0xb3, 0x3b, 0x79, 0x22, 0x55, 0x2c, 0x30, 0x51, + 0x5e, 0xf0, 0xec, 0x07, 0x60, 0x3c, 0x45, 0x26, 0xe3, 0x95, 0xd7, 0xcc, 0x57, 0x3e, 0xb4, 0x5b, + 0xca, 0x1c, 0xb2, 0xaf, 0xd2, 0x21, 0x13, 0x09, 0xc0, 0x81, 0x47, 0xfa, 0xf0, 0xc1, 0xa6, 0xf2, + 0xfc, 0x0b, 0x7d, 0xe6, 0xf9, 0x3f, 0x09, 0xe5, 0x56, 0xe0, 0xb9, 0x35, 0x57, 0x95, 0xf7, 0x65, + 0x95, 0x05, 0x56, 0x45, 0x1b, 0x56, 0x50, 0x74, 0x0b, 0x2a, 0x37, 0x6f, 0xc5, 0xfc, 0xf4, 0x47, + 0xf8, 0xb7, 0xf3, 0x3a, 0xf4, 0x51, 0x46, 0x8b, 0x3a, 0x5e, 0xc2, 0x9a, 0x17, 0xb2, 0x61, 0x90, + 0x29, 0x41, 0x99, 0x0c, 0xc4, 0x7c, 0xef, 0x4c, 0x3b, 0x46, 0x58, 0x40, 0xec, 0x2f, 0x57, 0xe0, + 0x74, 0xd6, 0xc5, 0x21, 0xe8, 0xfd, 0x30, 0xc8, 0xfb, 0x98, 0xcf, 0xdd, 0x54, 0x59, 0x3c, 0x16, + 0x18, 0x41, 0xd1, 0x2d, 0xf6, 0x1b, 0x0b, 0x9e, 0x82, 0xbb, 0xe7, 0xac, 0x8b, 0x19, 0x72, 0x34, + 0xdc, 0x97, 0x1c, 0xcd, 0x7d, 0xc9, 0xe1, 0xdc, 0x3d, 0x67, 0x1d, 0xed, 0x40, 0xa9, 0xe1, 0xc6, + 0xc4, 0x11, 0x4e, 0x84, 0x1b, 0x47, 0xc2, 0x9c, 0x38, 0xdc, 0x4a, 0x63, 0x3f, 0x31, 0x67, 0x88, + 0xbe, 0x64, 0xc1, 0xf8, 0x7a, 0xb2, 0xc0, 0x88, 0x10, 0x9e, 0xce, 0x11, 0x5c, 0x0e, 0x93, 0x64, + 0xc4, 0xef, 0x7b, 0x4c, 0x35, 0xe2, 0x74, 0x77, 0xd0, 0x47, 0x2c, 0x18, 0xda, 0x70, 0x3d, 0xa3, + 0xfa, 0xfe, 0x11, 0x7c, 0x9c, 0x8b, 0x8c, 0x81, 0xde, 0x71, 0xf0, 0xff, 0x11, 0x96, 0x9c, 0x7b, + 0x69, 0xaa, 0xc1, 0xc3, 0x6a, 0xaa, 0xa1, 0x7b, 0xa4, 0xa9, 0x3e, 0x6e, 0x41, 0x45, 0x8d, 0xb4, + 0x28, 0xd4, 0xf0, 0x9e, 0x23, 0xfc, 0xe4, 0xdc, 0x73, 0xa2, 0xfe, 0x62, 0xcd, 0x1c, 0x7d, 0xd6, + 0x82, 0x61, 0xe7, 0xb5, 0x76, 0x48, 0xea, 0x64, 0x3b, 0x68, 0x45, 0xa2, 0x7c, 0xe2, 0xcb, 0xf9, + 0x77, 0x66, 0x86, 0x32, 0x99, 0x27, 0xdb, 0x2b, 0xad, 0x48, 0x24, 0x2a, 0xea, 0x06, 0x6c, 0x76, + 0xc1, 0xde, 0x2d, 0xc0, 0xe4, 0x3e, 0x14, 0xd0, 0xf3, 0x30, 0x12, 0x84, 0x0d, 0xc7, 0x77, 0x5f, + 0x33, 0x2b, 0x06, 0x29, 0x2b, 0x6b, 0xc5, 0x80, 0xe1, 0x04, 0xa6, 0x59, 0x4a, 0xa2, 0xb0, 0x4f, + 0x29, 0x89, 0x73, 0x30, 0x10, 0x92, 0x56, 0x90, 0xde, 0x2c, 0xb0, 0x24, 0x21, 0x06, 0x41, 0x8f, + 0x42, 0xd1, 0x69, 0xb9, 0x22, 0xb4, 0x44, 0xed, 0x81, 0x66, 0x56, 0x17, 0x31, 0x6d, 0x4f, 0x54, + 0xb6, 0x29, 0x1d, 0x4b, 0x65, 0x1b, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0xa0, 0x56, 0x03, 0xc9, 0x33, + 0x05, 0xfb, 0xf5, 0x22, 0x3c, 0xba, 0xe7, 0x7c, 0xd1, 0x71, 0xa6, 0xd6, 0x1e, 0x71, 0xa6, 0x72, + 0x78, 0x0a, 0xfb, 0x0d, 0x4f, 0xb1, 0xc7, 0xf0, 0x7c, 0x84, 0x2e, 0x03, 0x59, 0x69, 0x29, 0x9f, + 0xeb, 0x7e, 0x7b, 0x15, 0x6e, 0x12, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, 0x89, 0x32, + 0x0a, 0xa5, 0x3c, 0xd4, 0x40, 0xcf, 0x6a, 0x47, 0x7c, 0xee, 0xf7, 0xaa, 0xcd, 0x60, 0xff, 0xf6, + 0x00, 0x3c, 0xde, 0x87, 0xf4, 0x36, 0x67, 0xb1, 0xd5, 0xe7, 0x2c, 0xfe, 0x1e, 0xff, 0x4c, 0x1f, + 0xcb, 0xfc, 0x4c, 0x38, 0xff, 0xcf, 0xb4, 0xf7, 0x17, 0x42, 0x4f, 0x41, 0xd9, 0xf5, 0x23, 0x52, + 0x6b, 0x87, 0x3c, 0xe6, 0xde, 0xc8, 0x20, 0x5c, 0x14, 0xed, 0x58, 0x61, 0xd0, 0x3d, 0x5d, 0xcd, + 0xa1, 0xcb, 0x7f, 0x28, 0xa7, 0xb4, 0x79, 0x33, 0x19, 0x91, 0x9b, 0x14, 0x73, 0x33, 0x54, 0x02, + 0x70, 0x36, 0xf6, 0xdf, 0xb5, 0xe0, 0x6c, 0x6f, 0x15, 0x8b, 0x9e, 0x81, 0xe1, 0x75, 0x16, 0xb8, + 0xc5, 0x2e, 0x7a, 0x97, 0x53, 0x87, 0xbd, 0xaf, 0x6e, 0xc6, 0x26, 0x0e, 0x9a, 0x83, 0x93, 0x66, + 0xc4, 0xd7, 0xb2, 0x11, 0x55, 0xc2, 0x9c, 0x00, 0x6b, 0x69, 0x20, 0xee, 0xc6, 0xb7, 0xbf, 0x5b, + 0xcc, 0xee, 0x16, 0x37, 0xc5, 0x0e, 0x32, 0x9b, 0xc5, 0x5c, 0x2d, 0xf4, 0x21, 0x71, 0x8b, 0xc7, + 0x2d, 0x71, 0x07, 0x7a, 0x49, 0x5c, 0x34, 0x0f, 0x27, 0x8c, 0x9b, 0xf8, 0x78, 0x21, 0x05, 0x1e, + 0x65, 0xa8, 0xaa, 0x20, 0xad, 0xa6, 0xe0, 0xb8, 0xeb, 0x89, 0xfb, 0x7c, 0xea, 0xfd, 0x6a, 0x01, + 0x1e, 0xea, 0x69, 0xfd, 0x1e, 0x93, 0x46, 0x31, 0x3f, 0xff, 0xc0, 0xf1, 0x7c, 0x7e, 0xf3, 0xa3, + 0x94, 0xf6, 0xfb, 0x28, 0xf6, 0x1f, 0x17, 0x7a, 0x2e, 0x04, 0xba, 0x13, 0xfa, 0xbe, 0x1d, 0xa5, + 0x17, 0x60, 0xd4, 0x69, 0xb5, 0x38, 0x1e, 0x8b, 0xd8, 0x4e, 0x55, 0x5d, 0x9b, 0x31, 0x81, 0x38, + 0x89, 0xdb, 0x97, 0x4d, 0xf3, 0xa7, 0x16, 0x54, 0x30, 0xd9, 0xe0, 0xd2, 0x08, 0xdd, 0x14, 0x43, + 0x64, 0xe5, 0x51, 0xf7, 0x9a, 0x0e, 0x6c, 0xe4, 0xb2, 0x7a, 0xd0, 0x59, 0x83, 0x7d, 0xd8, 0xbc, + 0x65, 0x75, 0x37, 0x5f, 0xb1, 0xf7, 0xdd, 0x7c, 0xf6, 0xb7, 0x87, 0xe8, 0xeb, 0xb5, 0x82, 0xb9, + 0x90, 0xd4, 0x23, 0xfa, 0x7d, 0xdb, 0xa1, 0x27, 0x26, 0x89, 0xfa, 0xbe, 0xd7, 0xf0, 0x12, 0xa6, + 0xed, 0x89, 0x03, 0xb2, 0xc2, 0x81, 0x6a, 0x4e, 0x15, 0xf7, 0xad, 0x39, 0xf5, 0x02, 0x8c, 0x46, + 0xd1, 0xe6, 0x6a, 0xe8, 0x6e, 0x3b, 0x31, 0xb9, 0x42, 0x3a, 0xc2, 0xf6, 0xd5, 0xf5, 0x57, 0xaa, + 0x97, 0x34, 0x10, 0x27, 0x71, 0xd1, 0x02, 0x9c, 0xd4, 0x95, 0x9f, 0x48, 0x18, 0xb3, 0x9c, 0x22, + 0x3e, 0x13, 0x54, 0xb1, 0x05, 0x5d, 0x2b, 0x4a, 0x20, 0xe0, 0xee, 0x67, 0xa8, 0x3c, 0x4d, 0x34, + 0xd2, 0x8e, 0x0c, 0x26, 0xe5, 0x69, 0x82, 0x0e, 0xed, 0x4b, 0xd7, 0x13, 0x68, 0x19, 0x4e, 0xf1, + 0x89, 0x31, 0xd3, 0x6a, 0x19, 0x6f, 0x34, 0x94, 0xac, 0x37, 0xbc, 0xd0, 0x8d, 0x82, 0xb3, 0x9e, + 0x43, 0xcf, 0xc1, 0xb0, 0x6a, 0x5e, 0x9c, 0x17, 0x67, 0x3b, 0xca, 0xb7, 0xa4, 0xc8, 0x2c, 0xd6, + 0xb1, 0x89, 0x87, 0xde, 0x0d, 0x0f, 0xea, 0xbf, 0x3c, 0xf1, 0x94, 0x1f, 0x78, 0xce, 0x8b, 0xa2, + 0x7a, 0xea, 0x9e, 0xb7, 0x85, 0x4c, 0xb4, 0x3a, 0xee, 0xf5, 0x3c, 0x5a, 0x87, 0xb3, 0x0a, 0x74, + 0xc1, 0x8f, 0x59, 0x16, 0x59, 0x44, 0x66, 0x9d, 0x88, 0x5c, 0x0b, 0x3d, 0x56, 0x86, 0xaf, 0xa2, + 0x2f, 0x0b, 0x5f, 0x70, 0xe3, 0x4b, 0x59, 0x98, 0x78, 0x09, 0xef, 0x41, 0x05, 0x4d, 0x43, 0x85, + 0xf8, 0xce, 0xba, 0x47, 0x56, 0xe6, 0x16, 0x59, 0x71, 0x3e, 0xe3, 0x7c, 0xf5, 0x82, 0x04, 0x60, + 0x8d, 0xa3, 0xe2, 0x7e, 0x47, 0x7a, 0x5e, 0x5c, 0xbf, 0x0a, 0xa7, 0x1b, 0xb5, 0x16, 0xb5, 0x08, + 0xdd, 0x1a, 0x99, 0xa9, 0xb1, 0x30, 0x47, 0xfa, 0x61, 0x78, 0x21, 0x68, 0x95, 0x40, 0xb1, 0x30, + 0xb7, 0xda, 0x85, 0x83, 0x33, 0x9f, 0x64, 0xe1, 0xb0, 0x61, 0xb0, 0xd3, 0x99, 0x38, 0x95, 0x0a, + 0x87, 0xa5, 0x8d, 0x98, 0xc3, 0xd0, 0x65, 0x40, 0x2c, 0x1b, 0xe7, 0x52, 0x1c, 0xb7, 0x94, 0x09, + 0x3a, 0x71, 0x3a, 0x59, 0x62, 0xeb, 0x62, 0x17, 0x06, 0xce, 0x78, 0x8a, 0x5a, 0x34, 0x7e, 0xc0, + 0xa8, 0x4f, 0x3c, 0x98, 0xb4, 0x68, 0xae, 0xf2, 0x66, 0x2c, 0xe1, 0xf6, 0x9f, 0x58, 0x30, 0xaa, + 0x96, 0xf6, 0x31, 0xa4, 0xcb, 0x79, 0xc9, 0x74, 0xb9, 0x85, 0xc3, 0x0b, 0x47, 0xd6, 0xf3, 0x1e, + 0x31, 0xe9, 0x5f, 0x1b, 0x06, 0xd0, 0x02, 0x54, 0xe9, 0x2e, 0xab, 0xa7, 0xee, 0xba, 0x6f, 0x85, + 0x57, 0x56, 0x31, 0xac, 0xd2, 0xbd, 0x2d, 0x86, 0x55, 0x85, 0x33, 0xd2, 0xb2, 0xe0, 0x87, 0x7d, + 0x97, 0x82, 0x48, 0xc9, 0xc2, 0xf2, 0xec, 0xa3, 0x82, 0xd0, 0x99, 0xc5, 0x2c, 0x24, 0x9c, 0xfd, + 0x6c, 0xc2, 0xa0, 0x19, 0xda, 0xd7, 0xca, 0x54, 0xcb, 0x7f, 0x69, 0x43, 0xde, 0x6e, 0x96, 0x5a, + 0xfe, 0x4b, 0x17, 0xab, 0x58, 0xe3, 0x64, 0xeb, 0x80, 0x4a, 0x4e, 0x3a, 0x00, 0x0e, 0xac, 0x03, + 0xa4, 0x34, 0x1a, 0xee, 0x29, 0x8d, 0xe4, 0xa1, 0xc2, 0x48, 0xcf, 0x43, 0x85, 0x77, 0xc0, 0x98, + 0xeb, 0x6f, 0x92, 0xd0, 0x8d, 0x49, 0x9d, 0xad, 0x05, 0x26, 0xa9, 0xca, 0xda, 0x02, 0x58, 0x4c, + 0x40, 0x71, 0x0a, 0x3b, 0x29, 0x42, 0xc7, 0xfa, 0x10, 0xa1, 0x3d, 0x14, 0xd7, 0x78, 0x3e, 0x8a, + 0xeb, 0xc4, 0xe1, 0x15, 0xd7, 0xc9, 0x23, 0x55, 0x5c, 0x28, 0x17, 0xc5, 0xd5, 0x97, 0x4e, 0x30, + 0x76, 0xa6, 0xa7, 0xf7, 0xd9, 0x99, 0xf6, 0xd2, 0x5a, 0x67, 0xee, 0x5a, 0x6b, 0x65, 0x2b, 0xa4, + 0x07, 0x8e, 0x5a, 0x21, 0x7d, 0xbc, 0x00, 0x67, 0xb4, 0xc8, 0xa6, 0x0b, 0xc5, 0xdd, 0xa0, 0x42, + 0x8b, 0xdd, 0xa5, 0xc9, 0xcf, 0xe8, 0x8c, 0xa4, 0x4b, 0x9d, 0xbf, 0xa9, 0x20, 0xd8, 0xc0, 0x62, + 0xb9, 0x8b, 0x24, 0x64, 0x85, 0xe7, 0xd3, 0xf2, 0x7c, 0x4e, 0xb4, 0x63, 0x85, 0x41, 0xa7, 0x22, + 0xfd, 0x2d, 0x72, 0xd0, 0xd3, 0x25, 0x4d, 0xe7, 0x34, 0x08, 0x9b, 0x78, 0xe8, 0x49, 0xce, 0x84, + 0xc9, 0x12, 0x2a, 0xd3, 0x47, 0xf8, 0x46, 0x44, 0x89, 0x0f, 0x05, 0x95, 0xdd, 0x61, 0x49, 0xaa, + 0xa5, 0xee, 0xee, 0xb0, 0x70, 0x37, 0x85, 0x61, 0xff, 0x4f, 0x0b, 0x1e, 0xca, 0x1c, 0x8a, 0x63, + 0xd0, 0xd3, 0x3b, 0x49, 0x3d, 0x5d, 0xcd, 0x6b, 0x13, 0x63, 0xbc, 0x45, 0x0f, 0x9d, 0xfd, 0x9f, + 0x2c, 0x18, 0xd3, 0xf8, 0xc7, 0xf0, 0xaa, 0x6e, 0xf2, 0x55, 0xf3, 0xdb, 0xaf, 0x55, 0xba, 0xde, + 0xed, 0xf7, 0x0a, 0xa0, 0xca, 0x0c, 0xcf, 0xd4, 0x64, 0x11, 0xf7, 0x7d, 0x4e, 0x8d, 0x3b, 0x30, + 0xc8, 0x0e, 0xbd, 0xa3, 0x7c, 0x02, 0x7a, 0x92, 0xfc, 0xd9, 0x01, 0xba, 0x0e, 0x28, 0x60, 0x7f, + 0x23, 0x2c, 0x18, 0xb2, 0x6b, 0x11, 0x78, 0x05, 0xd7, 0xba, 0x48, 0xc1, 0xd3, 0xd7, 0x22, 0x88, + 0x76, 0xac, 0x30, 0xa8, 0x26, 0x71, 0x6b, 0x81, 0x3f, 0xe7, 0x39, 0x91, 0xbc, 0x5e, 0x5b, 0x69, + 0x92, 0x45, 0x09, 0xc0, 0x1a, 0x87, 0x9d, 0x87, 0xbb, 0x51, 0xcb, 0x73, 0x3a, 0xc6, 0xae, 0xdc, + 0xa8, 0xb5, 0xa2, 0x40, 0xd8, 0xc4, 0xb3, 0x9b, 0x30, 0x91, 0x7c, 0x89, 0x79, 0xb2, 0xc1, 0x82, + 0x51, 0xfb, 0x1a, 0xce, 0x69, 0xa8, 0x38, 0xec, 0xa9, 0xa5, 0xb6, 0x23, 0x64, 0x82, 0x0e, 0xc9, + 0x94, 0x00, 0xac, 0x71, 0xec, 0x7f, 0x6a, 0xc1, 0xa9, 0x8c, 0x41, 0xcb, 0x31, 0xc5, 0x31, 0xd6, + 0xd2, 0x26, 0xcb, 0x06, 0xf8, 0x21, 0x18, 0xaa, 0x93, 0x0d, 0x47, 0x86, 0x3b, 0x1a, 0xd2, 0x73, + 0x9e, 0x37, 0x63, 0x09, 0xb7, 0x7f, 0xab, 0x00, 0xe3, 0xc9, 0xbe, 0x46, 0x2c, 0x6d, 0x88, 0x0f, + 0x93, 0x1b, 0xd5, 0x82, 0x6d, 0x12, 0x76, 0xe8, 0x9b, 0x5b, 0xa9, 0xb4, 0xa1, 0x2e, 0x0c, 0x9c, + 0xf1, 0x14, 0x2b, 0x32, 0x5e, 0x57, 0xa3, 0x2d, 0x67, 0xe4, 0xf5, 0x3c, 0x67, 0xa4, 0xfe, 0x98, + 0x66, 0x68, 0x84, 0x62, 0x89, 0x4d, 0xfe, 0xd4, 0x16, 0x61, 0x71, 0xd8, 0xb3, 0x6d, 0xd7, 0x8b, + 0x5d, 0x5f, 0xbc, 0xb2, 0x98, 0xab, 0xca, 0x16, 0x59, 0xee, 0x46, 0xc1, 0x59, 0xcf, 0xd9, 0xdf, + 0x19, 0x00, 0x95, 0xbe, 0xcf, 0x42, 0xd7, 0x72, 0x0a, 0xfc, 0x3b, 0x68, 0xf2, 0x99, 0x9a, 0x5b, + 0x03, 0x7b, 0xc5, 0x92, 0x70, 0x57, 0x8e, 0xe9, 0xcf, 0x55, 0x03, 0xb6, 0xa6, 0x41, 0xd8, 0xc4, + 0xa3, 0x3d, 0xf1, 0xdc, 0x6d, 0xc2, 0x1f, 0x1a, 0x4c, 0xf6, 0x64, 0x49, 0x02, 0xb0, 0xc6, 0xa1, + 0x3d, 0xa9, 0xbb, 0x1b, 0x1b, 0xc2, 0x2f, 0xa1, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xbf, 0x86, + 0x22, 0xd8, 0x12, 0xf6, 0xb7, 0x71, 0x0d, 0x45, 0xb0, 0x85, 0x19, 0x84, 0x7e, 0x25, 0x3f, 0x08, + 0x9b, 0x8e, 0xe7, 0xbe, 0x46, 0xea, 0x8a, 0x8b, 0xb0, 0xbb, 0xd5, 0x57, 0xba, 0xda, 0x8d, 0x82, + 0xb3, 0x9e, 0xa3, 0x13, 0xba, 0x15, 0x92, 0xba, 0x5b, 0x8b, 0x4d, 0x6a, 0x90, 0x9c, 0xd0, 0xab, + 0x5d, 0x18, 0x38, 0xe3, 0x29, 0x34, 0x03, 0xe3, 0xb2, 0xfc, 0x82, 0x2c, 0xe8, 0x35, 0x9c, 0x2c, + 0x20, 0x84, 0x93, 0x60, 0x9c, 0xc6, 0xa7, 0x42, 0xb2, 0x29, 0xca, 0x11, 0x32, 0x33, 0xdd, 0x10, + 0x92, 0xb2, 0x4c, 0x21, 0x56, 0x18, 0xf6, 0x87, 0x8b, 0x54, 0xa9, 0xf7, 0xa8, 0xfa, 0x79, 0x6c, + 0x81, 0xa6, 0xc9, 0x19, 0x39, 0xd0, 0xc7, 0x8c, 0x7c, 0x16, 0x46, 0x6e, 0x46, 0x81, 0xaf, 0x82, + 0x38, 0x4b, 0x3d, 0x83, 0x38, 0x0d, 0xac, 0xec, 0x20, 0xce, 0xc1, 0xbc, 0x82, 0x38, 0x87, 0xee, + 0x32, 0x88, 0xf3, 0x0f, 0x4a, 0xa0, 0xee, 0x19, 0xbb, 0x4a, 0xe2, 0x5b, 0x41, 0xb8, 0xe5, 0xfa, + 0x0d, 0x56, 0x4a, 0xe0, 0x4b, 0x96, 0xac, 0x46, 0xb0, 0x64, 0x26, 0xe1, 0x6d, 0xe4, 0x74, 0x57, + 0x54, 0x82, 0xd9, 0xd4, 0x9a, 0xc1, 0x28, 0x75, 0x1d, 0xba, 0x09, 0xc2, 0x89, 0x1e, 0xa1, 0x0f, + 0x00, 0x48, 0x27, 0xee, 0x86, 0x94, 0xc0, 0x8b, 0xf9, 0xf4, 0x0f, 0x93, 0x0d, 0x6d, 0x52, 0xaf, + 0x29, 0x26, 0xd8, 0x60, 0x88, 0x3e, 0xae, 0x13, 0x14, 0x79, 0xb6, 0xc7, 0xfb, 0x8e, 0x64, 0x6c, + 0xfa, 0x49, 0x4f, 0xc4, 0x30, 0xe4, 0xfa, 0x0d, 0x3a, 0x4f, 0x44, 0xb0, 0xdb, 0x5b, 0xb2, 0x4a, + 0xbe, 0x2c, 0x05, 0x4e, 0x7d, 0xd6, 0xf1, 0x1c, 0xbf, 0x46, 0xc2, 0x45, 0x8e, 0xae, 0x35, 0xa8, + 0x68, 0xc0, 0x92, 0x50, 0xd7, 0x65, 0x68, 0xa5, 0x7e, 0x2e, 0x43, 0x3b, 0xfb, 0x4e, 0x38, 0xd9, + 0xf5, 0x31, 0x0f, 0x94, 0x8d, 0x78, 0xf7, 0x89, 0x8c, 0xf6, 0x6f, 0x0f, 0x6a, 0xa5, 0x75, 0x35, + 0xa8, 0xf3, 0xbb, 0xb5, 0x42, 0xfd, 0x45, 0x85, 0xc9, 0x9c, 0xe3, 0x14, 0x51, 0x6a, 0xc6, 0x68, + 0xc4, 0x26, 0x4b, 0x3a, 0x47, 0x5b, 0x4e, 0x48, 0xfc, 0xa3, 0x9e, 0xa3, 0xab, 0x8a, 0x09, 0x36, + 0x18, 0xa2, 0xcd, 0x44, 0x3a, 0xd2, 0xc5, 0xc3, 0xa7, 0x23, 0xb1, 0x02, 0x7c, 0x59, 0x57, 0xd0, + 0x7c, 0xd6, 0x82, 0x31, 0x3f, 0x31, 0x73, 0xf3, 0x89, 0x40, 0xce, 0x5e, 0x15, 0xfc, 0x9a, 0xca, + 0x64, 0x1b, 0x4e, 0xf1, 0xcf, 0x52, 0x69, 0xa5, 0x03, 0xaa, 0x34, 0x7d, 0xb7, 0xdf, 0x60, 0xaf, + 0xbb, 0xfd, 0x90, 0xaf, 0x6e, 0x5c, 0x1d, 0xca, 0xfd, 0xc6, 0x55, 0xc8, 0xb8, 0x6d, 0xf5, 0x06, + 0x54, 0x6a, 0x21, 0x71, 0xe2, 0xbb, 0xbc, 0x7c, 0x93, 0xc5, 0x76, 0xcc, 0x49, 0x02, 0x58, 0xd3, + 0xb2, 0xff, 0xcf, 0x00, 0x9c, 0x90, 0x23, 0x22, 0xb3, 0x17, 0xa8, 0x7e, 0xe4, 0x7c, 0xb5, 0xad, + 0xac, 0xf4, 0xe3, 0x25, 0x09, 0xc0, 0x1a, 0x87, 0xda, 0x63, 0xed, 0x88, 0xac, 0xb4, 0x88, 0xbf, + 0xe4, 0xae, 0x47, 0xe2, 0x30, 0x56, 0x2d, 0x94, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0xdb, 0x3b, + 0x86, 0xd1, 0x6a, 0xd8, 0xf6, 0xd2, 0x50, 0x95, 0x70, 0xf4, 0x4b, 0x99, 0x65, 0xc8, 0xf3, 0xc9, + 0xf9, 0xeb, 0x4a, 0xda, 0x38, 0xe0, 0xd5, 0xd1, 0xff, 0xc8, 0x82, 0x33, 0xbc, 0x55, 0x8e, 0xe4, + 0xb5, 0x56, 0xdd, 0x89, 0x49, 0x94, 0xcf, 0xf5, 0x25, 0x19, 0xfd, 0xd3, 0xee, 0xe5, 0x2c, 0xb6, + 0x38, 0xbb, 0x37, 0xe8, 0x33, 0x16, 0x8c, 0x6f, 0x25, 0xca, 0xc5, 0x48, 0xd5, 0x71, 0xd8, 0x4a, + 0x0e, 0x09, 0xa2, 0x7a, 0xa9, 0x25, 0xdb, 0x23, 0x9c, 0xe6, 0x6e, 0xff, 0x0f, 0x0b, 0x4c, 0x31, + 0x7a, 0xfc, 0x55, 0x66, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xd4, 0xd3, 0xba, 0x7c, 0x14, 0x8a, + 0x6d, 0xb7, 0x2e, 0xf6, 0x17, 0xfa, 0x88, 0x78, 0x71, 0x1e, 0xd3, 0x76, 0xfb, 0x5f, 0x95, 0xb4, + 0x1b, 0x44, 0xa4, 0xd4, 0x7d, 0x5f, 0xbc, 0xf6, 0x86, 0xaa, 0xc3, 0xc8, 0xdf, 0xfc, 0x6a, 0x57, + 0x1d, 0xc6, 0x1f, 0x3f, 0x78, 0xc6, 0x24, 0x1f, 0xa0, 0x5e, 0x65, 0x18, 0x87, 0xf6, 0x49, 0x97, + 0xbc, 0x09, 0x65, 0xba, 0x05, 0x63, 0xfe, 0xcc, 0x72, 0xa2, 0x53, 0xe5, 0x4b, 0xa2, 0xfd, 0xce, + 0xee, 0xe4, 0x8f, 0x1d, 0xbc, 0x5b, 0xf2, 0x69, 0xac, 0xe8, 0xa3, 0x08, 0x2a, 0xf4, 0x37, 0xcb, + 0xec, 0x14, 0x9b, 0xbb, 0x6b, 0x4a, 0x66, 0x4a, 0x40, 0x2e, 0x69, 0xa3, 0x9a, 0x0f, 0xf2, 0xa1, + 0xc2, 0x6e, 0xd9, 0x67, 0x4c, 0xf9, 0x1e, 0x70, 0x55, 0xe5, 0x57, 0x4a, 0xc0, 0x9d, 0xdd, 0xc9, + 0x17, 0x0e, 0xce, 0x54, 0x3d, 0x8e, 0x35, 0x0b, 0xfb, 0x6f, 0x06, 0xf4, 0xdc, 0x15, 0xe5, 0x37, + 0xbf, 0x2f, 0xe6, 0xee, 0xf3, 0xa9, 0xb9, 0x7b, 0xae, 0x6b, 0xee, 0x8e, 0xe9, 0x2b, 0xd8, 0x13, + 0xb3, 0xf1, 0xb8, 0x0d, 0x81, 0xfd, 0xfd, 0x0d, 0xcc, 0x02, 0x7a, 0xb5, 0xed, 0x86, 0x24, 0x5a, + 0x0d, 0xdb, 0xbe, 0xeb, 0x37, 0xd8, 0x74, 0x2c, 0x9b, 0x16, 0x50, 0x02, 0x8c, 0xd3, 0xf8, 0x74, + 0x53, 0x4f, 0xbf, 0xf9, 0x0d, 0x67, 0x9b, 0xcf, 0x2a, 0xa3, 0x62, 0x5b, 0x55, 0xb4, 0x63, 0x85, + 0x81, 0x36, 0xe1, 0x11, 0x49, 0x60, 0x9e, 0x78, 0x44, 0xdc, 0xa1, 0xbe, 0xe1, 0x86, 0x4d, 0x1e, + 0x20, 0xce, 0x23, 0x13, 0xde, 0x2c, 0x28, 0x3c, 0x82, 0xf7, 0xc0, 0xc5, 0x7b, 0x52, 0xb2, 0xbf, + 0xca, 0xce, 0xeb, 0x8d, 0xe4, 0x75, 0x3a, 0xfb, 0x3c, 0xb7, 0xe9, 0xca, 0xc2, 0x72, 0x6a, 0xf6, + 0x2d, 0xd1, 0x46, 0xcc, 0x61, 0xe8, 0x16, 0x0c, 0xad, 0xf3, 0xab, 0x6e, 0xf3, 0xb9, 0x56, 0x43, + 0xdc, 0x9b, 0xcb, 0xaa, 0xb3, 0xca, 0x4b, 0x74, 0xef, 0xe8, 0x9f, 0x58, 0x72, 0xb3, 0xbf, 0x51, + 0x82, 0xf1, 0xd4, 0xbd, 0xf6, 0x89, 0x92, 0xd5, 0x85, 0x7d, 0x4b, 0x56, 0xbf, 0x17, 0xa0, 0x4e, + 0x5a, 0x5e, 0xd0, 0x61, 0x86, 0xdf, 0xc0, 0x81, 0x0d, 0x3f, 0xb5, 0x57, 0x98, 0x57, 0x54, 0xb0, + 0x41, 0x51, 0x54, 0xd3, 0xe3, 0x15, 0xb0, 0x53, 0xd5, 0xf4, 0x8c, 0xcb, 0x77, 0x06, 0x8f, 0xf7, + 0xf2, 0x1d, 0x17, 0xc6, 0x79, 0x17, 0x55, 0x8a, 0xf8, 0x5d, 0x64, 0x82, 0xb3, 0x24, 0x9b, 0xf9, + 0x24, 0x19, 0x9c, 0xa6, 0x6b, 0xde, 0xac, 0x53, 0x3e, 0xee, 0x9b, 0x75, 0xde, 0x0a, 0x15, 0xf9, + 0x9d, 0xa3, 0x89, 0x8a, 0x2e, 0xb3, 0x21, 0xa7, 0x41, 0x84, 0x35, 0xbc, 0xab, 0xda, 0x05, 0xdc, + 0xab, 0x6a, 0x17, 0xf6, 0xa7, 0x0b, 0x74, 0xc7, 0xc0, 0xfb, 0xa5, 0x0a, 0x37, 0x3d, 0x01, 0x83, + 0x4e, 0x3b, 0xde, 0x0c, 0xba, 0x2e, 0xcb, 0x9d, 0x61, 0xad, 0x58, 0x40, 0xd1, 0x12, 0x0c, 0xd4, + 0x75, 0x31, 0x9e, 0x83, 0x7c, 0x4f, 0xed, 0x7c, 0x75, 0x62, 0x82, 0x19, 0x15, 0xf4, 0x08, 0x0c, + 0xc4, 0x4e, 0x43, 0xe6, 0x05, 0xb2, 0x5c, 0xf0, 0x35, 0xa7, 0x11, 0x61, 0xd6, 0x7a, 0x90, 0x02, + 0xa4, 0x2f, 0xc0, 0x68, 0xe4, 0x36, 0x7c, 0x27, 0x6e, 0x87, 0xc4, 0x38, 0x9f, 0xd4, 0xd1, 0x29, + 0x26, 0x10, 0x27, 0x71, 0xed, 0xdf, 0x19, 0x81, 0xd3, 0xd5, 0xb9, 0x65, 0x79, 0x85, 0xc2, 0x91, + 0xa5, 0xf6, 0x65, 0xf1, 0x38, 0xbe, 0xd4, 0xbe, 0x1e, 0xdc, 0x3d, 0x23, 0xb5, 0xcf, 0x33, 0x52, + 0xfb, 0x92, 0x79, 0x56, 0xc5, 0x3c, 0xf2, 0xac, 0xb2, 0x7a, 0xd0, 0x4f, 0x9e, 0xd5, 0x91, 0xe5, + 0xfa, 0xed, 0xd9, 0xa1, 0x03, 0xe5, 0xfa, 0xa9, 0x44, 0xc8, 0x5c, 0x32, 0x60, 0x7a, 0x7c, 0xaa, + 0xcc, 0x44, 0x48, 0x95, 0x84, 0xc6, 0xb3, 0xbb, 0x84, 0xa8, 0x7f, 0x39, 0xff, 0x0e, 0xf4, 0x91, + 0x84, 0x26, 0x12, 0xcc, 0xcc, 0xc4, 0xc7, 0xa1, 0x3c, 0x12, 0x1f, 0xb3, 0xba, 0xb3, 0x6f, 0xe2, + 0xe3, 0x0b, 0x30, 0x5a, 0xf3, 0x02, 0x9f, 0xac, 0x86, 0x41, 0x1c, 0xd4, 0x02, 0x79, 0x5d, 0xa7, + 0xbe, 0x6d, 0xca, 0x04, 0xe2, 0x24, 0x6e, 0xaf, 0xac, 0xc9, 0xca, 0x61, 0xb3, 0x26, 0xe1, 0x1e, + 0x65, 0x4d, 0xfe, 0xac, 0xce, 0xef, 0x1f, 0x66, 0x5f, 0xe4, 0xbd, 0xf9, 0x7f, 0x91, 0xbe, 0xee, + 0xe3, 0x7c, 0x9d, 0xdf, 0x56, 0x4b, 0x4d, 0xf0, 0xb9, 0xa0, 0x49, 0x0d, 0xbf, 0x11, 0x36, 0x24, + 0xaf, 0x1c, 0xc1, 0x84, 0xbd, 0x51, 0xd5, 0x6c, 0xd4, 0x0d, 0xb6, 0xba, 0x09, 0x27, 0x3b, 0x72, + 0x98, 0xfa, 0x03, 0x5f, 0x28, 0xc0, 0x0f, 0xec, 0xdb, 0x05, 0x74, 0x0b, 0x20, 0x76, 0x1a, 0x62, + 0xa2, 0x8a, 0xa3, 0x99, 0x43, 0x86, 0x90, 0xae, 0x49, 0x7a, 0xbc, 0x70, 0x8e, 0xfa, 0xcb, 0x0e, + 0x3d, 0xe4, 0x6f, 0x16, 0x39, 0x1a, 0x78, 0x5d, 0xf5, 0x45, 0x71, 0xe0, 0x11, 0xcc, 0x20, 0x54, + 0xfd, 0x87, 0xa4, 0x41, 0x4d, 0xda, 0x62, 0x52, 0xfd, 0x63, 0xd6, 0x8a, 0x05, 0x14, 0x3d, 0x07, + 0xc3, 0x8e, 0xe7, 0xf1, 0xf4, 0x24, 0x12, 0x89, 0x6b, 0xe0, 0x74, 0xa1, 0x43, 0x0d, 0xc2, 0x26, + 0x9e, 0xfd, 0x57, 0x05, 0x98, 0xdc, 0x47, 0xa6, 0x74, 0xa5, 0xa5, 0x96, 0xfa, 0x4e, 0x4b, 0x15, + 0x29, 0x1b, 0x83, 0x3d, 0x52, 0x36, 0x9e, 0x83, 0xe1, 0x98, 0x38, 0x4d, 0x11, 0x74, 0x26, 0x7c, + 0x0e, 0xfa, 0xac, 0x59, 0x83, 0xb0, 0x89, 0x47, 0xa5, 0xd8, 0x98, 0x53, 0xab, 0x91, 0x28, 0x92, + 0x39, 0x19, 0xc2, 0x6f, 0x9b, 0x5b, 0xc2, 0x07, 0x73, 0x87, 0xcf, 0x24, 0x58, 0xe0, 0x14, 0xcb, + 0xf4, 0x80, 0x57, 0xfa, 0x1c, 0xf0, 0x2f, 0x17, 0xe0, 0xd1, 0x3d, 0xb5, 0x5b, 0xdf, 0xe9, 0x32, + 0xed, 0x88, 0x84, 0xe9, 0x89, 0x73, 0x2d, 0x22, 0x21, 0x66, 0x10, 0x3e, 0x4a, 0xad, 0x96, 0x0a, + 0x18, 0xce, 0x3f, 0x77, 0x8c, 0x8f, 0x52, 0x82, 0x05, 0x4e, 0xb1, 0xbc, 0xdb, 0x69, 0xf9, 0x8d, + 0x01, 0x78, 0xbc, 0x0f, 0x1b, 0x20, 0xc7, 0x1c, 0xbb, 0x64, 0x3e, 0x68, 0xf1, 0x1e, 0xe5, 0x83, + 0xde, 0xdd, 0x70, 0xbd, 0x91, 0x46, 0xda, 0x57, 0x2e, 0xdf, 0x57, 0x0b, 0x70, 0xb6, 0xb7, 0xc1, + 0x82, 0xde, 0x0e, 0xe3, 0xa1, 0x0a, 0xb2, 0x33, 0x53, 0x49, 0x4f, 0x71, 0xcf, 0x4e, 0x02, 0x84, + 0xd3, 0xb8, 0x68, 0x0a, 0xa0, 0xe5, 0xc4, 0x9b, 0xd1, 0x85, 0x1d, 0x37, 0x8a, 0x45, 0x41, 0xa9, + 0x31, 0x7e, 0x96, 0x28, 0x5b, 0xb1, 0x81, 0x41, 0xd9, 0xb1, 0x7f, 0xf3, 0xc1, 0xd5, 0x20, 0xe6, + 0x0f, 0xf1, 0xcd, 0xd6, 0x29, 0x79, 0xbd, 0x94, 0x01, 0xc2, 0x69, 0x5c, 0xca, 0x8e, 0x9d, 0x56, + 0xf3, 0x8e, 0xf2, 0x5d, 0x18, 0x63, 0xb7, 0xa4, 0x5a, 0xb1, 0x81, 0x91, 0x4e, 0x92, 0x2d, 0xed, + 0x9f, 0x24, 0x6b, 0xff, 0xcb, 0x02, 0x3c, 0xd4, 0xd3, 0xe0, 0xed, 0x4f, 0x4c, 0xdd, 0x7f, 0x89, + 0xad, 0x77, 0xb9, 0xc2, 0x0e, 0x96, 0x10, 0xf9, 0xa7, 0x3d, 0x66, 0x9a, 0x48, 0x88, 0xbc, 0xfb, + 0x3a, 0x0f, 0xf7, 0xdf, 0x78, 0x76, 0xe5, 0x40, 0x0e, 0x1c, 0x20, 0x07, 0x32, 0xf5, 0x31, 0x4a, + 0x7d, 0x6a, 0x87, 0x3f, 0x1f, 0xe8, 0x39, 0xbc, 0x74, 0x83, 0xdc, 0x97, 0xdf, 0x7c, 0x1e, 0x4e, + 0xb8, 0x3e, 0xbb, 0x6a, 0xb0, 0xda, 0x5e, 0x17, 0x35, 0x86, 0x78, 0x21, 0x4d, 0x95, 0x68, 0xb1, + 0x98, 0x82, 0xe3, 0xae, 0x27, 0xee, 0xc3, 0x9c, 0xd4, 0xbb, 0x1b, 0xd2, 0x03, 0x4a, 0xee, 0x15, + 0x38, 0x23, 0x87, 0x62, 0xd3, 0x09, 0x49, 0x5d, 0x28, 0xdb, 0x48, 0xa4, 0xd6, 0x3c, 0xc4, 0xd3, + 0x73, 0x32, 0x10, 0x70, 0xf6, 0x73, 0xec, 0x76, 0xb7, 0xa0, 0xe5, 0xd6, 0xc4, 0x56, 0x50, 0xdf, + 0xee, 0x46, 0x1b, 0x31, 0x87, 0x69, 0x7d, 0x51, 0x39, 0x1e, 0x7d, 0xf1, 0x5e, 0xa8, 0xa8, 0xf1, + 0xe6, 0x59, 0x02, 0x6a, 0x92, 0x77, 0x65, 0x09, 0xa8, 0x19, 0x6e, 0x60, 0xed, 0x77, 0x33, 0xf2, + 0x8f, 0xc0, 0x88, 0xf2, 0x7e, 0xf5, 0x7b, 0xc7, 0x9e, 0xfd, 0x7f, 0x0b, 0x90, 0xba, 0x05, 0x07, + 0xed, 0x40, 0xa5, 0x2e, 0xef, 0x26, 0xce, 0xa7, 0x90, 0xab, 0xba, 0xea, 0x58, 0x1f, 0xff, 0xa8, + 0x26, 0xac, 0x99, 0xa1, 0xf7, 0xf3, 0x9a, 0xa9, 0x82, 0x75, 0x21, 0x8f, 0xbc, 0xe4, 0xaa, 0xa2, + 0x67, 0x5e, 0xa2, 0x25, 0xdb, 0xb0, 0xc1, 0x0f, 0xc5, 0x50, 0xd9, 0x94, 0xb7, 0xfd, 0xe4, 0x23, + 0xee, 0xd4, 0xe5, 0x41, 0xdc, 0x44, 0x53, 0x7f, 0xb1, 0x66, 0x64, 0xff, 0x49, 0x01, 0x4e, 0x27, + 0x3f, 0x80, 0x38, 0xae, 0xfb, 0x35, 0x0b, 0x1e, 0xf4, 0x9c, 0x28, 0xae, 0xb6, 0xd9, 0x46, 0x61, + 0xa3, 0xed, 0xad, 0xa4, 0xca, 0xeb, 0x1e, 0xd6, 0xd9, 0xa2, 0x08, 0xa7, 0x6f, 0x87, 0x9a, 0x7d, + 0xf8, 0xf6, 0xee, 0xe4, 0x83, 0x4b, 0xd9, 0xcc, 0x71, 0xaf, 0x5e, 0xa1, 0xcf, 0x5a, 0x70, 0xa2, + 0xd6, 0x0e, 0x43, 0xe2, 0xc7, 0xba, 0xab, 0xfc, 0x2b, 0x5e, 0xcd, 0x65, 0x20, 0x75, 0x07, 0x4f, + 0x53, 0x81, 0x3a, 0x97, 0xe2, 0x85, 0xbb, 0xb8, 0xdb, 0xbf, 0x40, 0x35, 0x67, 0xcf, 0xf7, 0xfc, + 0x5b, 0x76, 0x9d, 0xd5, 0x5f, 0x0c, 0xc2, 0x68, 0xa2, 0x86, 0x70, 0xe2, 0x88, 0xcb, 0xda, 0xf7, + 0x88, 0x8b, 0x25, 0x83, 0xb5, 0x7d, 0x79, 0xd9, 0xae, 0x91, 0x0c, 0xd6, 0xf6, 0x09, 0xe6, 0x30, + 0x31, 0xa4, 0xb8, 0xed, 0x8b, 0xe8, 0x76, 0x73, 0x48, 0x71, 0xdb, 0xc7, 0x02, 0x8a, 0x3e, 0x64, + 0xc1, 0x08, 0x5b, 0x7c, 0xe2, 0x80, 0x50, 0x28, 0xb4, 0xcb, 0x39, 0x2c, 0x77, 0x59, 0x2f, 0x9b, + 0x45, 0x43, 0x9a, 0x2d, 0x38, 0xc1, 0x11, 0x7d, 0xd4, 0x82, 0x8a, 0xba, 0x9f, 0x4f, 0xdc, 0x9c, + 0x5d, 0xcd, 0xb7, 0x44, 0x73, 0x4a, 0xea, 0xa9, 0x5a, 0xb9, 0x58, 0x33, 0x46, 0x91, 0x3a, 0xbd, + 0x1b, 0x3a, 0x9a, 0xd3, 0x3b, 0xc8, 0x38, 0xb9, 0x7b, 0x2b, 0x54, 0x9a, 0x8e, 0xef, 0x6e, 0x90, + 0x28, 0xe6, 0x07, 0x6a, 0xb2, 0x72, 0xbc, 0x6c, 0xc4, 0x1a, 0x4e, 0x8d, 0xfd, 0x88, 0xbd, 0x58, + 0x6c, 0x9c, 0x80, 0x31, 0x63, 0xbf, 0xaa, 0x9b, 0xb1, 0x89, 0x63, 0x1e, 0xd7, 0xc1, 0x3d, 0x3d, + 0xae, 0x1b, 0xde, 0xe7, 0xb8, 0xae, 0x0a, 0x67, 0x9c, 0x76, 0x1c, 0x5c, 0x22, 0x8e, 0x37, 0xc3, + 0x6f, 0xe8, 0x8f, 0x78, 0xd9, 0xe9, 0x11, 0xe6, 0x02, 0x56, 0xf1, 0x5b, 0x55, 0xe2, 0x6d, 0x74, + 0x21, 0xe1, 0xec, 0x67, 0xed, 0x7f, 0x6e, 0xc1, 0x99, 0xcc, 0xa9, 0x70, 0xff, 0x46, 0xce, 0xdb, + 0x9f, 0x2f, 0xc1, 0xa9, 0x8c, 0x0a, 0xe3, 0xa8, 0x63, 0x2e, 0x12, 0x2b, 0x8f, 0x20, 0xb4, 0x64, + 0x4c, 0x95, 0xfc, 0x36, 0x19, 0x2b, 0xe3, 0x60, 0x27, 0xf0, 0xfa, 0x14, 0xbc, 0x78, 0xbc, 0xa7, + 0xe0, 0xc6, 0x5c, 0x1f, 0xb8, 0xa7, 0x73, 0xbd, 0xb4, 0xcf, 0x5c, 0xff, 0x9a, 0x05, 0x13, 0xcd, + 0x1e, 0xd7, 0xda, 0x88, 0xf3, 0xa4, 0xeb, 0x47, 0x73, 0x69, 0xce, 0xec, 0x23, 0xb7, 0x77, 0x27, + 0x7b, 0xde, 0x26, 0x84, 0x7b, 0xf6, 0xca, 0xfe, 0x4e, 0x11, 0x98, 0xbd, 0xc6, 0xaa, 0xc8, 0x76, + 0xd0, 0x07, 0xcd, 0x8b, 0x0a, 0xac, 0xbc, 0x8a, 0xea, 0x73, 0xe2, 0xea, 0xa2, 0x03, 0x3e, 0x82, + 0x59, 0xf7, 0x1e, 0xa4, 0x25, 0x61, 0xa1, 0x0f, 0x49, 0xe8, 0xc9, 0x1b, 0x21, 0x8a, 0xf9, 0xdf, + 0x08, 0x51, 0x49, 0xdf, 0x06, 0xb1, 0xf7, 0x27, 0x1e, 0xb8, 0x2f, 0x3f, 0xf1, 0x2f, 0x5b, 0x5c, + 0xf0, 0xa4, 0xbe, 0x82, 0x36, 0x37, 0xac, 0x3d, 0xcc, 0x8d, 0xa7, 0xa0, 0x1c, 0x09, 0xc9, 0x2c, + 0xcc, 0x12, 0x1d, 0x00, 0x25, 0xda, 0xb1, 0xc2, 0xa0, 0xbb, 0x2e, 0xc7, 0xf3, 0x82, 0x5b, 0x17, + 0x9a, 0xad, 0xb8, 0x23, 0x0c, 0x14, 0xb5, 0x2d, 0x98, 0x51, 0x10, 0x6c, 0x60, 0xd9, 0x9b, 0x60, + 0x6c, 0x18, 0xee, 0xfe, 0x16, 0xd0, 0x3e, 0xae, 0x6f, 0xfe, 0x87, 0x05, 0xc1, 0x8a, 0x6f, 0x00, + 0x9e, 0x4f, 0x5d, 0x97, 0xdd, 0x7f, 0xa8, 0xdb, 0xfb, 0x01, 0x6a, 0x41, 0xb3, 0x45, 0xb7, 0xc4, + 0x6b, 0x41, 0x3e, 0xfb, 0xa8, 0x39, 0x45, 0x4f, 0x0f, 0x98, 0x6e, 0xc3, 0x06, 0xbf, 0x84, 0xd4, + 0x2e, 0xee, 0x2b, 0xb5, 0x13, 0x02, 0x6c, 0x60, 0x6f, 0x01, 0x66, 0xff, 0x95, 0x05, 0x09, 0x83, + 0x0e, 0xb5, 0xa0, 0x44, 0xbb, 0xdb, 0x11, 0xb2, 0x60, 0x25, 0x3f, 0xeb, 0x91, 0x0a, 0x61, 0xb1, + 0xc0, 0xd8, 0x4f, 0xcc, 0x19, 0x21, 0x4f, 0x84, 0xf5, 0xe5, 0xb2, 0xaf, 0x31, 0x19, 0x5e, 0x0a, + 0x82, 0x2d, 0x1e, 0x19, 0xa3, 0x43, 0x04, 0xed, 0xe7, 0xe1, 0x64, 0x57, 0xa7, 0xd8, 0xcd, 0xa1, + 0x81, 0xdc, 0x9c, 0x1b, 0x0b, 0x83, 0x55, 0x39, 0xc0, 0x1c, 0x66, 0x7f, 0xd5, 0x82, 0x13, 0x69, + 0xf2, 0xe8, 0x75, 0x0b, 0x4e, 0x46, 0x69, 0x7a, 0x47, 0x35, 0x76, 0x2a, 0x34, 0xbf, 0x0b, 0x84, + 0xbb, 0x3b, 0x61, 0xff, 0x8d, 0x98, 0xfc, 0x37, 0x5c, 0xbf, 0x1e, 0xdc, 0x52, 0x26, 0x90, 0xd5, + 0xd3, 0x04, 0xa2, 0x2b, 0xbf, 0xb6, 0x49, 0xea, 0x6d, 0xaf, 0xab, 0x66, 0x42, 0x55, 0xb4, 0x63, + 0x85, 0xc1, 0x52, 0xc4, 0xdb, 0x62, 0x4b, 0x9a, 0x9a, 0x94, 0xf3, 0xa2, 0x1d, 0x2b, 0x0c, 0xf4, + 0x2c, 0x8c, 0x18, 0x2f, 0x29, 0xe7, 0x25, 0xdb, 0x4f, 0x18, 0xca, 0x39, 0xc2, 0x09, 0x2c, 0x34, + 0x05, 0xa0, 0xcc, 0x29, 0xa9, 0x8c, 0x99, 0x0f, 0x5d, 0xc9, 0xbc, 0x08, 0x1b, 0x18, 0xac, 0x20, + 0x83, 0xd7, 0x8e, 0xd8, 0x21, 0xf1, 0xa0, 0x2e, 0x98, 0x3e, 0x27, 0xda, 0xb0, 0x82, 0x52, 0xb9, + 0xd5, 0x74, 0xfc, 0xb6, 0xe3, 0xd1, 0x11, 0x12, 0x5e, 0x31, 0xb5, 0x0c, 0x97, 0x15, 0x04, 0x1b, + 0x58, 0xf4, 0x8d, 0x63, 0xb7, 0x49, 0x5e, 0x0a, 0x7c, 0x19, 0x52, 0xad, 0xe3, 0x06, 0x44, 0x3b, + 0x56, 0x18, 0xf6, 0x5f, 0x5a, 0x30, 0xae, 0x2b, 0xc1, 0x30, 0x5f, 0x56, 0xc2, 0x89, 0x67, 0xed, + 0xeb, 0xc4, 0x4b, 0xd6, 0xbd, 0x28, 0xf4, 0x55, 0xf7, 0xc2, 0x2c, 0x49, 0x51, 0xdc, 0xb3, 0x24, + 0xc5, 0x0f, 0xc2, 0xd0, 0x16, 0xe9, 0x18, 0xb5, 0x2b, 0x86, 0xa9, 0x39, 0x74, 0x85, 0x37, 0x61, + 0x09, 0x43, 0x36, 0x0c, 0xd6, 0x1c, 0x55, 0x31, 0x6d, 0x84, 0x6f, 0x7d, 0xe6, 0x66, 0x18, 0x92, + 0x80, 0xd8, 0x2b, 0x50, 0x51, 0xc7, 0xe7, 0xd2, 0xa7, 0x66, 0x65, 0xfb, 0xd4, 0xfa, 0x4a, 0x8d, + 0x9f, 0x5d, 0xff, 0xfa, 0x77, 0x1f, 0x7b, 0xd3, 0x1f, 0x7d, 0xf7, 0xb1, 0x37, 0x7d, 0xfb, 0xbb, + 0x8f, 0xbd, 0xe9, 0x43, 0xb7, 0x1f, 0xb3, 0xbe, 0x7e, 0xfb, 0x31, 0xeb, 0x8f, 0x6e, 0x3f, 0x66, + 0x7d, 0xfb, 0xf6, 0x63, 0xd6, 0x77, 0x6e, 0x3f, 0x66, 0x7d, 0xf6, 0xbf, 0x3e, 0xf6, 0xa6, 0x97, + 0x32, 0x63, 0xea, 0xe9, 0x8f, 0xa7, 0x6b, 0xf5, 0xe9, 0xed, 0xf3, 0x2c, 0xac, 0x9b, 0x2e, 0xaf, + 0x69, 0x63, 0x4e, 0x4d, 0xcb, 0xe5, 0xf5, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xfc, 0x44, + 0xf5, 0xc0, 0xf5, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -7222,6 +7457,11 @@ func (m *ApplicationSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x72 i -= len(m.Ref) copy(dAtA[i:], m.Ref) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Ref))) @@ -7369,6 +7609,22 @@ func (m *ApplicationSourceHelm) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.SkipSchemaValidation { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x78 + i-- + if m.SkipTests { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x70 if len(m.APIVersions) > 0 { for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.APIVersions[iNdEx]) @@ -7859,6 +8115,18 @@ func (m *ApplicationSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SourceHydrator != nil { + { + size, err := m.SourceHydrator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } if len(m.Sources) > 0 { for iNdEx := len(m.Sources) - 1; iNdEx >= 0; iNdEx-- { { @@ -7968,6 +8236,16 @@ func (m *ApplicationStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.SourceHydrator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 i -= len(m.ControllerNamespace) copy(dAtA[i:], m.ControllerNamespace) i = encodeVarintGenerated(dAtA, i, uint64(len(m.ControllerNamespace))) @@ -8656,6 +8934,19 @@ func (m *ClusterConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.ProxyUrl) + copy(dAtA[i:], m.ProxyUrl) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ProxyUrl))) + i-- + dAtA[i] = 0x42 + i-- + if m.DisableCompression { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 if m.ExecProviderConfig != nil { { size, err := m.ExecProviderConfig.MarshalToSizedBuffer(dAtA[:i]) @@ -8728,6 +9019,14 @@ func (m *ClusterGenerator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.FlatList { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 if len(m.Values) > 0 { keysForValues := make([]string, 0, len(m.Values)) for k := range m.Values { @@ -9168,6 +9467,44 @@ func (m *ConnectionState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *DrySource) 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 *DrySource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DrySource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x1a + i -= len(m.TargetRevision) + copy(dAtA[i:], m.TargetRevision) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetRevision))) + i-- + dAtA[i] = 0x12 + i -= len(m.RepoURL) + copy(dAtA[i:], m.RepoURL) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.RepoURL))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *DuckTypeGenerator) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9666,6 +10003,18 @@ func (m *HealthStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.LastTransitionTime != nil { + { + size, err := m.LastTransitionTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } i -= len(m.Message) copy(dAtA[i:], m.Message) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -9874,6 +10223,109 @@ func (m *HostResourceInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *HydrateOperation) 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 *HydrateOperation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HydrateOperation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.SourceHydrator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + i -= len(m.HydratedSHA) + copy(dAtA[i:], m.HydratedSHA) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.HydratedSHA))) + i-- + dAtA[i] = 0x32 + i -= len(m.DrySHA) + copy(dAtA[i:], m.DrySHA) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DrySHA))) + i-- + dAtA[i] = 0x2a + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x22 + i -= len(m.Phase) + copy(dAtA[i:], m.Phase) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Phase))) + i-- + dAtA[i] = 0x1a + if m.FinishedAt != nil { + { + size, err := m.FinishedAt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size, err := m.StartedAt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *HydrateTo) 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 *HydrateTo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HydrateTo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.TargetBranch) + copy(dAtA[i:], m.TargetBranch) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetBranch))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *Info) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -13160,6 +13612,14 @@ func (m *ResourceStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.RequiresDeletionConfirmation { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 i = encodeVarintGenerated(dAtA, i, uint64(m.SyncWave)) i-- dAtA[i] = 0x50 @@ -14169,6 +14629,151 @@ func (m *SignatureKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SourceHydrator) 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 *SourceHydrator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SourceHydrator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.HydrateTo != nil { + { + size, err := m.HydrateTo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + { + size, err := m.SyncSource.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.DrySource.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *SourceHydratorStatus) 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 *SourceHydratorStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SourceHydratorStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CurrentOperation != nil { + { + size, err := m.CurrentOperation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.LastSuccessfulOperation != nil { + { + size, err := m.LastSuccessfulOperation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SuccessfulHydrateOperation) 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 *SuccessfulHydrateOperation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SuccessfulHydrateOperation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.SourceHydrator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + i -= len(m.HydratedSHA) + copy(dAtA[i:], m.HydratedSHA) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.HydratedSHA))) + i-- + dAtA[i] = 0x32 + i -= len(m.DrySHA) + copy(dAtA[i:], m.DrySHA) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DrySHA))) + i-- + dAtA[i] = 0x2a + return len(dAtA) - i, nil +} + func (m *SyncOperation) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -14189,6 +14794,9 @@ func (m *SyncOperation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.SelfHealAttemptsCount)) + i-- + dAtA[i] = 0x60 if len(m.Revisions) > 0 { for iNdEx := len(m.Revisions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Revisions[iNdEx]) @@ -14537,6 +15145,39 @@ func (m *SyncPolicyAutomated) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SyncSource) 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 *SyncSource) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SyncSource) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + i -= len(m.TargetBranch) + copy(dAtA[i:], m.TargetBranch) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TargetBranch))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *SyncStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -15623,6 +16264,8 @@ func (m *ApplicationSource) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Ref) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -15689,6 +16332,8 @@ func (m *ApplicationSourceHelm) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 2 + n += 2 return n } @@ -15873,6 +16518,10 @@ func (m *ApplicationSpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.SourceHydrator != nil { + l = m.SourceHydrator.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -15930,6 +16579,8 @@ func (m *ApplicationStatus) Size() (n int) { } l = len(m.ControllerNamespace) n += 1 + l + sovGenerated(uint64(l)) + l = m.SourceHydrator.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -16161,6 +16812,9 @@ func (m *ClusterConfig) Size() (n int) { l = m.ExecProviderConfig.Size() n += 1 + l + sovGenerated(uint64(l)) } + n += 2 + l = len(m.ProxyUrl) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -16182,6 +16836,7 @@ func (m *ClusterGenerator) Size() (n int) { n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } + n += 2 return n } @@ -16333,6 +16988,21 @@ func (m *ConnectionState) Size() (n int) { return n } +func (m *DrySource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RepoURL) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.TargetRevision) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Path) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *DuckTypeGenerator) Size() (n int) { if m == nil { return 0 @@ -16523,6 +17193,10 @@ func (m *HealthStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) + if m.LastTransitionTime != nil { + l = m.LastTransitionTime.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -16601,6 +17275,42 @@ func (m *HostResourceInfo) Size() (n int) { return n } +func (m *HydrateOperation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.StartedAt.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.FinishedAt != nil { + l = m.FinishedAt.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.Phase) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Message) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.DrySHA) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.HydratedSHA) + n += 1 + l + sovGenerated(uint64(l)) + l = m.SourceHydrator.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *HydrateTo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TargetBranch) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *Info) Size() (n int) { if m == nil { return 0 @@ -17845,6 +18555,7 @@ func (m *ResourceStatus) Size() (n int) { n += 2 n += 2 n += 1 + sovGenerated(uint64(m.SyncWave)) + n += 2 return n } @@ -18187,6 +18898,55 @@ func (m *SignatureKey) Size() (n int) { return n } +func (m *SourceHydrator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.DrySource.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.SyncSource.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.HydrateTo != nil { + l = m.HydrateTo.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *SourceHydratorStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LastSuccessfulOperation != nil { + l = m.LastSuccessfulOperation.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.CurrentOperation != nil { + l = m.CurrentOperation.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *SuccessfulHydrateOperation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DrySHA) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.HydratedSHA) + n += 1 + l + sovGenerated(uint64(l)) + l = m.SourceHydrator.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *SyncOperation) Size() (n int) { if m == nil { return 0 @@ -18235,6 +18995,7 @@ func (m *SyncOperation) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 1 + sovGenerated(uint64(m.SelfHealAttemptsCount)) return n } @@ -18329,6 +19090,19 @@ func (m *SyncPolicyAutomated) Size() (n int) { return n } +func (m *SyncSource) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TargetBranch) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Path) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *SyncStatus) Size() (n int) { if m == nil { return 0 @@ -18990,6 +19764,7 @@ func (this *ApplicationSource) String() string { `Plugin:` + strings.Replace(this.Plugin.String(), "ApplicationSourcePlugin", "ApplicationSourcePlugin", 1) + `,`, `Chart:` + fmt.Sprintf("%v", this.Chart) + `,`, `Ref:` + fmt.Sprintf("%v", this.Ref) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `}`, }, "") return s @@ -19035,6 +19810,8 @@ func (this *ApplicationSourceHelm) String() string { `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `KubeVersion:` + fmt.Sprintf("%v", this.KubeVersion) + `,`, `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, + `SkipTests:` + fmt.Sprintf("%v", this.SkipTests) + `,`, + `SkipSchemaValidation:` + fmt.Sprintf("%v", this.SkipSchemaValidation) + `,`, `}`, }, "") return s @@ -19179,6 +19956,7 @@ func (this *ApplicationSpec) String() string { `Info:` + repeatedStringForInfo + `,`, `RevisionHistoryLimit:` + valueToStringGenerated(this.RevisionHistoryLimit) + `,`, `Sources:` + repeatedStringForSources + `,`, + `SourceHydrator:` + strings.Replace(this.SourceHydrator.String(), "SourceHydrator", "SourceHydrator", 1) + `,`, `}`, }, "") return s @@ -19216,6 +19994,7 @@ func (this *ApplicationStatus) String() string { `ResourceHealthSource:` + fmt.Sprintf("%v", this.ResourceHealthSource) + `,`, `SourceTypes:` + fmt.Sprintf("%v", this.SourceTypes) + `,`, `ControllerNamespace:` + fmt.Sprintf("%v", this.ControllerNamespace) + `,`, + `SourceHydrator:` + strings.Replace(strings.Replace(this.SourceHydrator.String(), "SourceHydratorStatus", "SourceHydratorStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -19390,6 +20169,8 @@ func (this *ClusterConfig) String() string { `TLSClientConfig:` + strings.Replace(strings.Replace(this.TLSClientConfig.String(), "TLSClientConfig", "TLSClientConfig", 1), `&`, ``, 1) + `,`, `AWSAuthConfig:` + strings.Replace(this.AWSAuthConfig.String(), "AWSAuthConfig", "AWSAuthConfig", 1) + `,`, `ExecProviderConfig:` + strings.Replace(this.ExecProviderConfig.String(), "ExecProviderConfig", "ExecProviderConfig", 1) + `,`, + `DisableCompression:` + fmt.Sprintf("%v", this.DisableCompression) + `,`, + `ProxyUrl:` + fmt.Sprintf("%v", this.ProxyUrl) + `,`, `}`, }, "") return s @@ -19412,6 +20193,7 @@ func (this *ClusterGenerator) String() string { `Selector:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1), `&`, ``, 1) + `,`, `Template:` + strings.Replace(strings.Replace(this.Template.String(), "ApplicationSetTemplate", "ApplicationSetTemplate", 1), `&`, ``, 1) + `,`, `Values:` + mapStringForValues + `,`, + `FlatList:` + fmt.Sprintf("%v", this.FlatList) + `,`, `}`, }, "") return s @@ -19528,6 +20310,18 @@ func (this *ConnectionState) String() string { }, "") return s } +func (this *DrySource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DrySource{`, + `RepoURL:` + fmt.Sprintf("%v", this.RepoURL) + `,`, + `TargetRevision:` + fmt.Sprintf("%v", this.TargetRevision) + `,`, + `Path:` + fmt.Sprintf("%v", this.Path) + `,`, + `}`, + }, "") + return s +} func (this *DuckTypeGenerator) String() string { if this == nil { return "nil" @@ -19693,6 +20487,7 @@ func (this *HealthStatus) String() string { s := strings.Join([]string{`&HealthStatus{`, `Status:` + fmt.Sprintf("%v", this.Status) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `LastTransitionTime:` + strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1) + `,`, `}`, }, "") return s @@ -19760,6 +20555,32 @@ func (this *HostResourceInfo) String() string { }, "") return s } +func (this *HydrateOperation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&HydrateOperation{`, + `StartedAt:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.StartedAt), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, + `FinishedAt:` + strings.Replace(fmt.Sprintf("%v", this.FinishedAt), "Time", "v1.Time", 1) + `,`, + `Phase:` + fmt.Sprintf("%v", this.Phase) + `,`, + `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `DrySHA:` + fmt.Sprintf("%v", this.DrySHA) + `,`, + `HydratedSHA:` + fmt.Sprintf("%v", this.HydratedSHA) + `,`, + `SourceHydrator:` + strings.Replace(strings.Replace(this.SourceHydrator.String(), "SourceHydrator", "SourceHydrator", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *HydrateTo) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&HydrateTo{`, + `TargetBranch:` + fmt.Sprintf("%v", this.TargetBranch) + `,`, + `}`, + }, "") + return s +} func (this *Info) String() string { if this == nil { return "nil" @@ -20705,6 +21526,7 @@ func (this *ResourceStatus) String() string { `Hook:` + fmt.Sprintf("%v", this.Hook) + `,`, `RequiresPruning:` + fmt.Sprintf("%v", this.RequiresPruning) + `,`, `SyncWave:` + fmt.Sprintf("%v", this.SyncWave) + `,`, + `RequiresDeletionConfirmation:` + fmt.Sprintf("%v", this.RequiresDeletionConfirmation) + `,`, `}`, }, "") return s @@ -20934,6 +21756,41 @@ func (this *SignatureKey) String() string { }, "") return s } +func (this *SourceHydrator) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SourceHydrator{`, + `DrySource:` + strings.Replace(strings.Replace(this.DrySource.String(), "DrySource", "DrySource", 1), `&`, ``, 1) + `,`, + `SyncSource:` + strings.Replace(strings.Replace(this.SyncSource.String(), "SyncSource", "SyncSource", 1), `&`, ``, 1) + `,`, + `HydrateTo:` + strings.Replace(this.HydrateTo.String(), "HydrateTo", "HydrateTo", 1) + `,`, + `}`, + }, "") + return s +} +func (this *SourceHydratorStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SourceHydratorStatus{`, + `LastSuccessfulOperation:` + strings.Replace(this.LastSuccessfulOperation.String(), "SuccessfulHydrateOperation", "SuccessfulHydrateOperation", 1) + `,`, + `CurrentOperation:` + strings.Replace(this.CurrentOperation.String(), "HydrateOperation", "HydrateOperation", 1) + `,`, + `}`, + }, "") + return s +} +func (this *SuccessfulHydrateOperation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SuccessfulHydrateOperation{`, + `DrySHA:` + fmt.Sprintf("%v", this.DrySHA) + `,`, + `HydratedSHA:` + fmt.Sprintf("%v", this.HydratedSHA) + `,`, + `SourceHydrator:` + strings.Replace(strings.Replace(this.SourceHydrator.String(), "SourceHydrator", "SourceHydrator", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func (this *SyncOperation) String() string { if this == nil { return "nil" @@ -20959,6 +21816,7 @@ func (this *SyncOperation) String() string { `SyncOptions:` + fmt.Sprintf("%v", this.SyncOptions) + `,`, `Sources:` + repeatedStringForSources + `,`, `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, + `SelfHealAttemptsCount:` + fmt.Sprintf("%v", this.SelfHealAttemptsCount) + `,`, `}`, }, "") return s @@ -21026,6 +21884,17 @@ func (this *SyncPolicyAutomated) String() string { }, "") return s } +func (this *SyncSource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SyncSource{`, + `TargetBranch:` + fmt.Sprintf("%v", this.TargetBranch) + `,`, + `Path:` + fmt.Sprintf("%v", this.Path) + `,`, + `}`, + }, "") + return s +} func (this *SyncStatus) String() string { if this == nil { return "nil" @@ -27127,6 +27996,38 @@ func (m *ApplicationSource) Unmarshal(dAtA []byte) error { } m.Ref = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -27732,6 +28633,46 @@ func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { } m.APIVersions = append(m.APIVersions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipTests", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SkipTests = bool(v != 0) + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipSchemaValidation", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SkipSchemaValidation = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -29236,6 +30177,42 @@ func (m *ApplicationSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceHydrator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SourceHydrator == nil { + m.SourceHydrator = &SourceHydrator{} + } + if err := m.SourceHydrator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -29723,61 +30700,11 @@ func (m *ApplicationStatus) Unmarshal(dAtA []byte) error { } m.ControllerNamespace = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplicationSummary) 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 ErrIntOverflowGenerated - } - 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: ApplicationSummary: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationSummary: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExternalURLs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SourceHydrator", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -29787,55 +30714,24 @@ func (m *ApplicationSummary) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.ExternalURLs = append(m.ExternalURLs, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - 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 ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.SourceHydrator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Images = append(m.Images, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -29858,7 +30754,7 @@ func (m *ApplicationSummary) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationTree) Unmarshal(dAtA []byte) error { +func (m *ApplicationSummary) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -29881,17 +30777,17 @@ func (m *ApplicationTree) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationTree: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationSummary: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationTree: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationSummary: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ExternalURLs", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -29901,65 +30797,29 @@ func (m *ApplicationTree) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Nodes = append(m.Nodes, ResourceNode{}) - if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ExternalURLs = append(m.ExternalURLs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OrphanedNodes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.OrphanedNodes = append(m.OrphanedNodes, ResourceNode{}) - if err := m.OrphanedNodes[len(m.OrphanedNodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -29969,45 +30829,24 @@ func (m *ApplicationTree) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Hosts = append(m.Hosts, HostInfo{}) - if err := m.Hosts[len(m.Hosts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Images = append(m.Images, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ShardsCount", wireType) - } - m.ShardsCount = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ShardsCount |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -30029,7 +30868,7 @@ func (m *ApplicationTree) Unmarshal(dAtA []byte) error { } return nil } -func (m *ApplicationWatchEvent) Unmarshal(dAtA []byte) error { +func (m *ApplicationTree) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -30052,47 +30891,218 @@ func (m *ApplicationWatchEvent) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ApplicationWatchEvent: wiretype end group for non-group") + return fmt.Errorf("proto: ApplicationTree: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ApplicationWatchEvent: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ApplicationTree: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - 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 ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = k8s_io_apimachinery_pkg_watch.EventType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Application", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Nodes = append(m.Nodes, ResourceNode{}) + if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrphanedNodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OrphanedNodes = append(m.OrphanedNodes, ResourceNode{}) + if err := m.OrphanedNodes[len(m.OrphanedNodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hosts = append(m.Hosts, HostInfo{}) + if err := m.Hosts[len(m.Hosts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ShardsCount", wireType) + } + m.ShardsCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ShardsCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationWatchEvent) 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 ErrIntOverflowGenerated + } + 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: ApplicationWatchEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationWatchEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = k8s_io_apimachinery_pkg_watch.EventType(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Application", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -31707,6 +32717,58 @@ func (m *ClusterConfig) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DisableCompression", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DisableCompression = bool(v != 0) + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProxyUrl", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProxyUrl = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -31950,6 +33012,26 @@ func (m *ClusterGenerator) Unmarshal(dAtA []byte) error { } m.Values[mapkey] = mapvalue iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FlatList", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.FlatList = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -33166,6 +34248,152 @@ func (m *ConnectionState) Unmarshal(dAtA []byte) error { } return nil } +func (m *DrySource) 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 ErrIntOverflowGenerated + } + 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: DrySource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DrySource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RepoURL", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RepoURL = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetRevision", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetRevision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *DuckTypeGenerator) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -34922,15 +36150,361 @@ func (m *HealthStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HealthStatus: wiretype end group for non-group") + return fmt.Errorf("proto: HealthStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HealthStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Status = github_com_argoproj_gitops_engine_pkg_health.HealthStatusCode(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastTransitionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LastTransitionTime == nil { + m.LastTransitionTime = &v1.Time{} + } + if err := m.LastTransitionTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HelmFileParameter) 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 ErrIntOverflowGenerated + } + 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: HelmFileParameter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HelmFileParameter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HelmOptions) 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 ErrIntOverflowGenerated + } + 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: HelmOptions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HelmOptions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValuesFileSchemes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValuesFileSchemes = append(m.ValuesFileSchemes, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HelmParameter) 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 ErrIntOverflowGenerated + } + 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: HelmParameter: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HealthStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HelmParameter: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -34958,11 +36532,11 @@ func (m *HealthStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Status = github_com_argoproj_gitops_engine_pkg_health.HealthStatusCode(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -34990,8 +36564,28 @@ func (m *HealthStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Message = string(dAtA[iNdEx:postIndex]) + m.Value = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ForceString", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ForceString = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -35013,7 +36607,7 @@ func (m *HealthStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *HelmFileParameter) Unmarshal(dAtA []byte) error { +func (m *HostInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -35036,10 +36630,10 @@ func (m *HelmFileParameter) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HelmFileParameter: wiretype end group for non-group") + return fmt.Errorf("proto: HostInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HelmFileParameter: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HostInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -35076,9 +36670,9 @@ func (m *HelmFileParameter) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourcesInfo", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -35088,23 +36682,58 @@ func (m *HelmFileParameter) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + m.ResourcesInfo = append(m.ResourcesInfo, HostResourceInfo{}) + if err := m.ResourcesInfo[len(m.ResourcesInfo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SystemInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SystemInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -35127,7 +36756,7 @@ func (m *HelmFileParameter) Unmarshal(dAtA []byte) error { } return nil } -func (m *HelmOptions) Unmarshal(dAtA []byte) error { +func (m *HostResourceInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -35150,15 +36779,15 @@ func (m *HelmOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HelmOptions: wiretype end group for non-group") + return fmt.Errorf("proto: HostResourceInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HelmOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HostResourceInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValuesFileSchemes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -35186,8 +36815,65 @@ func (m *HelmOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ValuesFileSchemes = append(m.ValuesFileSchemes, string(dAtA[iNdEx:postIndex])) + m.ResourceName = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestedByApp", wireType) + } + m.RequestedByApp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RequestedByApp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestedByNeighbors", wireType) + } + m.RequestedByNeighbors = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RequestedByNeighbors |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + } + m.Capacity = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Capacity |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -35209,7 +36895,7 @@ func (m *HelmOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *HelmParameter) Unmarshal(dAtA []byte) error { +func (m *HydrateOperation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -35232,17 +36918,17 @@ func (m *HelmParameter) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HelmParameter: wiretype end group for non-group") + return fmt.Errorf("proto: HydrateOperation: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HelmParameter: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HydrateOperation: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StartedAt", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -35252,27 +36938,64 @@ func (m *HelmParameter) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + if err := m.StartedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field FinishedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.FinishedAt == nil { + m.FinishedAt = &v1.Time{} + } + if err := m.FinishedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Phase", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -35300,13 +37023,13 @@ func (m *HelmParameter) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Value = string(dAtA[iNdEx:postIndex]) + m.Phase = HydrateOperationPhase(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ForceString", wireType) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -35316,65 +37039,27 @@ func (m *HelmParameter) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.ForceString = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HostInfo) 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 ErrIntOverflowGenerated + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - if iNdEx >= l { + if postIndex > 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: HostInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HostInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DrySHA", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -35402,13 +37087,13 @@ func (m *HostInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.DrySHA = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourcesInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field HydratedSHA", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -35418,29 +37103,27 @@ func (m *HostInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.ResourcesInfo = append(m.ResourcesInfo, HostResourceInfo{}) - if err := m.ResourcesInfo[len(m.ResourcesInfo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.HydratedSHA = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SystemInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SourceHydrator", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -35467,7 +37150,7 @@ func (m *HostInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.SystemInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SourceHydrator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -35492,7 +37175,7 @@ func (m *HostInfo) Unmarshal(dAtA []byte) error { } return nil } -func (m *HostResourceInfo) Unmarshal(dAtA []byte) error { +func (m *HydrateTo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -35515,15 +37198,15 @@ func (m *HostResourceInfo) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HostResourceInfo: wiretype end group for non-group") + return fmt.Errorf("proto: HydrateTo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HostResourceInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HydrateTo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TargetBranch", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -35551,65 +37234,8 @@ func (m *HostResourceInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ResourceName = k8s_io_api_core_v1.ResourceName(dAtA[iNdEx:postIndex]) + m.TargetBranch = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RequestedByApp", wireType) - } - m.RequestedByApp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RequestedByApp |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RequestedByNeighbors", wireType) - } - m.RequestedByNeighbors = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RequestedByNeighbors |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) - } - m.Capacity = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Capacity |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -47185,6 +48811,26 @@ func (m *ResourceStatus) Unmarshal(dAtA []byte) error { break } } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RequiresDeletionConfirmation", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RequiresDeletionConfirmation = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -50215,15 +51861,371 @@ func (m *SignatureKey) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SignatureKey: wiretype end group for non-group") + return fmt.Errorf("proto: SignatureKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignatureKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SourceHydrator) 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 ErrIntOverflowGenerated + } + 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: SourceHydrator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SourceHydrator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DrySource", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DrySource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SyncSource", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SyncSource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HydrateTo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.HydrateTo == nil { + m.HydrateTo = &HydrateTo{} + } + if err := m.HydrateTo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SourceHydratorStatus) 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 ErrIntOverflowGenerated + } + 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: SourceHydratorStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SignatureKey: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SourceHydratorStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field KeyID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastSuccessfulOperation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LastSuccessfulOperation == nil { + m.LastSuccessfulOperation = &SuccessfulHydrateOperation{} + } + if err := m.LastSuccessfulOperation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentOperation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CurrentOperation == nil { + m.CurrentOperation = &HydrateOperation{} + } + if err := m.CurrentOperation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SuccessfulHydrateOperation) 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 ErrIntOverflowGenerated + } + 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: SuccessfulHydrateOperation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SuccessfulHydrateOperation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DrySHA", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -50251,7 +52253,72 @@ func (m *SignatureKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.KeyID = string(dAtA[iNdEx:postIndex]) + m.DrySHA = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HydratedSHA", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HydratedSHA = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceHydrator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SourceHydrator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -50611,6 +52678,25 @@ func (m *SyncOperation) Unmarshal(dAtA []byte) error { } m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SelfHealAttemptsCount", wireType) + } + m.SelfHealAttemptsCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SelfHealAttemptsCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -51361,6 +53447,120 @@ func (m *SyncPolicyAutomated) Unmarshal(dAtA []byte) error { } return nil } +func (m *SyncSource) 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 ErrIntOverflowGenerated + } + 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: SyncSource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SyncSource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetBranch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetBranch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + 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 ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *SyncStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index 0b79d47202cb9..6823a76261de4 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -156,7 +156,7 @@ message ApplicationDestinationServiceAccount { // Namespace specifies the target namespace for the application's resources. optional string namespace = 2; - // ServiceAccountName to be used for impersonation during the sync operation + // DefaultServiceAccount to be used for impersonation during the sync operation optional string defaultServiceAccount = 3; } @@ -454,6 +454,9 @@ message ApplicationSource { // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. optional string ref = 13; + + // Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications. + optional string name = 14; } // ApplicationSourceDirectory holds options for applications of type plain YAML or Jsonnet @@ -515,6 +518,12 @@ message ApplicationSourceHelm { // APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, // Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. repeated string apiVersions = 13; + + // SkipTests skips test manifest installation step (Helm's --skip-tests). + optional bool skipTests = 14; + + // SkipSchemaValidation skips JSON schema validation (Helm's --skip-schema-validation) + optional bool skipSchemaValidation = 15; } // ApplicationSourceJsonnet holds options specific to applications of type Jsonnet @@ -635,6 +644,9 @@ message ApplicationSpec { // Sources is a reference to the location of the application's manifests or chart repeated ApplicationSource sources = 8; + + // SourceHydrator provides a way to push hydrated manifests back to git before syncing them to the cluster. + optional SourceHydrator sourceHydrator = 9; } // ApplicationStatus contains status information for the application @@ -678,6 +690,9 @@ message ApplicationStatus { // ControllerNamespace indicates the namespace in which the application controller is located optional string controllerNamespace = 13; + + // SourceHydrator stores information about the current state of source hydration + optional SourceHydratorStatus sourceHydrator = 14; } // ApplicationSummary contains information about URLs and container images used by an application @@ -838,6 +853,12 @@ message ClusterConfig { // ExecProviderConfig contains configuration for an exec provider optional ExecProviderConfig execProviderConfig = 6; + + // DisableCompression bypasses automatic GZip compression requests to the server. + optional bool disableCompression = 7; + + // ProxyURL is the URL to the proxy to be used for all requests send to the server + optional string proxyUrl = 8; } // ClusterGenerator defines a generator to match against clusters registered with ArgoCD. @@ -851,6 +872,9 @@ message ClusterGenerator { // Values contains key/value pairs which are passed directly as parameters to the template map values = 3; + + // returns the clusters a single 'clusters' value in the template + optional bool flatList = 4; } // ClusterInfo contains information about the cluster @@ -939,6 +963,18 @@ message ConnectionState { optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time attemptedAt = 3; } +// DrySource specifies a location for dry "don't repeat yourself" manifest source information. +message DrySource { + // RepoURL is the URL to the git repository that contains the application manifests + optional string repoURL = 1; + + // TargetRevision defines the revision of the source to hydrate + optional string targetRevision = 2; + + // Path is a directory path within the Git repository where the manifests are located + optional string path = 3; +} + // DuckType defines a generator to match against clusters registered with ArgoCD. message DuckTypeGenerator { // ConfigMapRef is a ConfigMap with the duck type definitions needed to retrieve the data @@ -1054,6 +1090,9 @@ message HealthStatus { // Message is a human-readable informational message describing the health status optional string message = 2; + + // LastTransitionTime is the time the HealthStatus was set or updated + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; } // HelmFileParameter is a file parameter that's passed to helm template during manifest generation @@ -1104,6 +1143,37 @@ message HostResourceInfo { optional int64 capacity = 4; } +// HydrateOperation contains information about the most recent hydrate operation +message HydrateOperation { + // StartedAt indicates when the hydrate operation started + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 1; + + // FinishedAt indicates when the hydrate operation finished + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 2; + + // Phase indicates the status of the hydrate operation + optional string phase = 3; + + // Message contains a message describing the current status of the hydrate operation + optional string message = 4; + + // DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation + optional string drySHA = 5; + + // HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation + optional string hydratedSHA = 6; + + // SourceHydrator holds the hydrator config used for the hydrate operation + optional SourceHydrator sourceHydrator = 7; +} + +// HydrateTo specifies a location to which hydrated manifests should be pushed as a "staging area" before being moved to +// the SyncSource. The RepoURL and Path are assumed based on the associated SyncSource config in the SourceHydrator. +message HydrateTo { + // TargetBranch is the branch to which hydrated manifests should be committed + optional string targetBranch = 1; +} + message Info { optional string name = 1; @@ -1956,6 +2026,8 @@ message ResourceStatus { optional bool requiresPruning = 9; optional int64 syncWave = 10; + + optional bool requiresDeletionConfirmation = 11; } // RetryStrategy contains information about the strategy to apply when a sync failed @@ -2221,6 +2293,41 @@ message SignatureKey { optional string keyID = 1; } +// SourceHydrator specifies a dry "don't repeat yourself" source for manifests, a sync source from which to sync +// hydrated manifests, and an optional hydrateTo location to act as a "staging" aread for hydrated manifests. +message SourceHydrator { + // DrySource specifies where the dry "don't repeat yourself" manifest source lives. + optional DrySource drySource = 1; + + // SyncSource specifies where to sync hydrated manifests from. + optional SyncSource syncSource = 2; + + // HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + // have to move manifests to the SyncSource, e.g. by pull request. + optional HydrateTo hydrateTo = 3; +} + +// SourceHydratorStatus contains information about the current state of source hydration +message SourceHydratorStatus { + // LastSuccessfulOperation holds info about the most recent successful hydration + optional SuccessfulHydrateOperation lastSuccessfulOperation = 1; + + // CurrentOperation holds the status of the hydrate operation + optional HydrateOperation currentOperation = 2; +} + +// SuccessfulHydrateOperation contains information about the most recent successful hydrate operation +message SuccessfulHydrateOperation { + // DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation + optional string drySHA = 5; + + // HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation + optional string hydratedSHA = 6; + + // SourceHydrator holds the hydrator config used for the hydrate operation + optional SourceHydrator sourceHydrator = 7; +} + // SyncOperation contains details about a sync operation. message SyncOperation { // Revision is the revision (Git) or chart version (Helm) which to sync the application to @@ -2256,6 +2363,9 @@ message SyncOperation { // Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to // If omitted, will use the revision specified in app spec. repeated string revisions = 11; + + // SelfHealAttemptsCount contains the number of auto-heal attempts + optional int64 autoHealAttemptsCount = 12; } // SyncOperationResource contains resources to sync. @@ -2317,6 +2427,17 @@ message SyncPolicyAutomated { optional bool allowEmpty = 3; } +// SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the +// associated DrySource config in the SourceHydrator. +message SyncSource { + // TargetBranch is the branch to which hydrated manifests should be committed + optional string targetBranch = 1; + + // Path is a directory path within the git repository where hydrated manifests should be committed to and synced + // from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + optional string path = 2; +} + // SyncStatus contains information about the currently observed live and desired states of an application message SyncStatus { // Status is the sync state of the comparison diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 1b2533532bc0e..28492686a8003 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -72,6 +72,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigManagementPlugin": schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef": schema_pkg_apis_application_v1alpha1_ConfigMapKeyRef(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConnectionState": schema_pkg_apis_application_v1alpha1_ConnectionState(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource": schema_pkg_apis_application_v1alpha1_DrySource(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DuckTypeGenerator": schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.EnvEntry": schema_pkg_apis_application_v1alpha1_EnvEntry(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ErrApplicationNotAllowedToUseProject": schema_pkg_apis_application_v1alpha1_ErrApplicationNotAllowedToUseProject(ref), @@ -87,6 +88,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "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), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation": schema_pkg_apis_application_v1alpha1_HydrateOperation(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo": schema_pkg_apis_application_v1alpha1_HydrateTo(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info": schema_pkg_apis_application_v1alpha1_Info(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.InfoItem": schema_pkg_apis_application_v1alpha1_InfoItem(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.JWTToken": schema_pkg_apis_application_v1alpha1_JWTToken(ref), @@ -158,11 +161,15 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SCMProviderGeneratorGitlab": schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef": schema_pkg_apis_application_v1alpha1_SecretRef(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SignatureKey": schema_pkg_apis_application_v1alpha1_SignatureKey(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator": schema_pkg_apis_application_v1alpha1_SourceHydrator(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus": schema_pkg_apis_application_v1alpha1_SourceHydratorStatus(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation": schema_pkg_apis_application_v1alpha1_SuccessfulHydrateOperation(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperation": schema_pkg_apis_application_v1alpha1_SyncOperation(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResource": schema_pkg_apis_application_v1alpha1_SyncOperationResource(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncOperationResult": schema_pkg_apis_application_v1alpha1_SyncOperationResult(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy": schema_pkg_apis_application_v1alpha1_SyncPolicy(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicyAutomated": schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref), + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource": schema_pkg_apis_application_v1alpha1_SyncSource(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus": schema_pkg_apis_application_v1alpha1_SyncStatus(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategy": schema_pkg_apis_application_v1alpha1_SyncStrategy(ref), "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStrategyApply": schema_pkg_apis_application_v1alpha1_SyncStrategyApply(ref), @@ -2317,12 +2324,18 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSpec(ref common.ReferenceCa }, }, }, + "sourceHydrator": { + SchemaProps: spec.SchemaProps{ + Description: "SourceHydrator provides a way to push hydrated manifests back to git before syncing them to the cluster.", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), + }, + }, }, Required: []string{"destination", "project"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.Info", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceIgnoreDifferences", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncPolicy"}, } } @@ -2450,11 +2463,18 @@ func schema_pkg_apis_application_v1alpha1_ApplicationStatus(ref common.Reference Format: "", }, }, + "sourceHydrator": { + SchemaProps: spec.SchemaProps{ + Description: "SourceHydrator stores information about the current state of source hydration", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationCondition", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSummary", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HealthStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationState", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ResourceStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.RevisionHistory", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydratorStatus", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -2997,6 +3017,13 @@ func schema_pkg_apis_application_v1alpha1_ClusterGenerator(ref common.ReferenceC }, }, }, + "flatList": { + SchemaProps: spec.SchemaProps{ + Description: "returns the clusters a single 'clusters' value in the template", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, @@ -3339,6 +3366,44 @@ func schema_pkg_apis_application_v1alpha1_ConnectionState(ref common.ReferenceCa } } +func schema_pkg_apis_application_v1alpha1_DrySource(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DrySource specifies a location for dry \"don't repeat yourself\" manifest source information.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "repoURL": { + SchemaProps: spec.SchemaProps{ + Description: "RepoURL is the URL to the git repository that contains the application manifests", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "targetRevision": { + SchemaProps: spec.SchemaProps{ + Description: "TargetRevision defines the revision of the source to hydrate", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Path is a directory path within the Git repository where the manifests are located", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"repoURL", "targetRevision", "path"}, + }, + }, + } +} + func schema_pkg_apis_application_v1alpha1_DuckTypeGenerator(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3780,9 +3845,17 @@ func schema_pkg_apis_application_v1alpha1_HealthStatus(ref common.ReferenceCallb Format: "", }, }, + "lastTransitionTime": { + SchemaProps: spec.SchemaProps{ + Description: "LastTransitionTime is the time the HealthStatus was set", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), + }, + }, }, }, }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } @@ -3951,6 +4024,93 @@ func schema_pkg_apis_application_v1alpha1_HostResourceInfo(ref common.ReferenceC } } +func schema_pkg_apis_application_v1alpha1_HydrateOperation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "HydrateOperation contains information about the most recent hydrate operation", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "startedAt": { + SchemaProps: spec.SchemaProps{ + Description: "StartedAt indicates when the hydrate operation started", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), + }, + }, + "finishedAt": { + SchemaProps: spec.SchemaProps{ + Description: "FinishedAt indicates when the hydrate operation finished", + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Time"), + }, + }, + "phase": { + SchemaProps: spec.SchemaProps{ + Description: "Phase indicates the status of the hydrate operation", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "Message contains a message describing the current status of the hydrate operation", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "drySHA": { + SchemaProps: spec.SchemaProps{ + Description: "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation", + Type: []string{"string"}, + Format: "", + }, + }, + "hydratedSHA": { + SchemaProps: spec.SchemaProps{ + Description: "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation", + Type: []string{"string"}, + Format: "", + }, + }, + "sourceHydrator": { + SchemaProps: spec.SchemaProps{ + Description: "SourceHydrator holds the hydrator config used for the hydrate operation", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), + }, + }, + }, + Required: []string{"phase", "message"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + } +} + +func schema_pkg_apis_application_v1alpha1_HydrateTo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "HydrateTo specifies a location to which hydrated manifests should be pushed as a \"staging area\" before being moved to the SyncSource. The RepoURL and Path are assumed based on the associated SyncSource config in the SourceHydrator.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "targetBranch": { + SchemaProps: spec.SchemaProps{ + Description: "TargetBranch is the branch to which hydrated manifests should be committed", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"targetBranch"}, + }, + }, + } +} + func schema_pkg_apis_application_v1alpha1_Info(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -7636,6 +7796,105 @@ func schema_pkg_apis_application_v1alpha1_SignatureKey(ref common.ReferenceCallb } } +func schema_pkg_apis_application_v1alpha1_SourceHydrator(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SourceHydrator specifies a dry \"don't repeat yourself\" source for manifests, a sync source from which to sync hydrated manifests, and an optional hydrateTo location to act as a \"staging\" aread for hydrated manifests.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "drySource": { + SchemaProps: spec.SchemaProps{ + Description: "DrySource specifies where the dry \"don't repeat yourself\" manifest source lives.", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource"), + }, + }, + "syncSource": { + SchemaProps: spec.SchemaProps{ + Description: "SyncSource specifies where to sync hydrated manifests from.", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource"), + }, + }, + "hydrateTo": { + SchemaProps: spec.SchemaProps{ + Description: "HydrateTo specifies an optional \"staging\" location to push hydrated manifests to. An external system would then have to move manifests to the SyncSource, e.g. by pull request.", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo"), + }, + }, + }, + Required: []string{"drySource", "syncSource"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.DrySource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateTo", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SyncSource"}, + } +} + +func schema_pkg_apis_application_v1alpha1_SourceHydratorStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SourceHydratorStatus contains information about the current state of source hydration", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "lastSuccessfulOperation": { + SchemaProps: spec.SchemaProps{ + Description: "LastSuccessfulOperation holds info about the most recent successful hydration", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"), + }, + }, + "currentOperation": { + SchemaProps: spec.SchemaProps{ + Description: "CurrentOperation holds the status of the hydrate operation", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.HydrateOperation", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SuccessfulHydrateOperation"}, + } +} + +func schema_pkg_apis_application_v1alpha1_SuccessfulHydrateOperation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SuccessfulHydrateOperation contains information about the most recent successful hydrate operation", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "drySHA": { + SchemaProps: spec.SchemaProps{ + Description: "DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation", + Type: []string{"string"}, + Format: "", + }, + }, + "hydratedSHA": { + SchemaProps: spec.SchemaProps{ + Description: "HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation", + Type: []string{"string"}, + Format: "", + }, + }, + "sourceHydrator": { + SchemaProps: spec.SchemaProps{ + Description: "SourceHydrator holds the hydrator config used for the hydrate operation", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SourceHydrator"}, + } +} + func schema_pkg_apis_application_v1alpha1_SyncOperation(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -7958,6 +8217,36 @@ func schema_pkg_apis_application_v1alpha1_SyncPolicyAutomated(ref common.Referen } } +func schema_pkg_apis_application_v1alpha1_SyncSource(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the associated DrySource config in the SourceHydrator.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "targetBranch": { + SchemaProps: spec.SchemaProps{ + Description: "TargetBranch is the branch to which hydrated manifests should be committed", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "Path is a directory path within the git repository where hydrated manifests should be committed to and synced from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"targetBranch", "path"}, + }, + }, + } +} + func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 5a30d24fbcfdb..047ae14b1ac97 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -5,6 +5,7 @@ import ( "net/url" "strings" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/util/cert" "github.com/argoproj/argo-cd/v2/util/git" "github.com/argoproj/argo-cd/v2/util/helm" @@ -283,6 +284,34 @@ func (m *Repository) StringForLogging() string { return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", m.Repo, m.Type, m.Name, m.Project) } +// Sanitized returns a copy of the Repository with sensitive information removed. +func (m *Repository) Sanitized() *Repository { + return &Repository{ + Repo: m.Repo, + Type: m.Type, + Name: m.Name, + Username: m.Username, + Insecure: m.IsInsecure(), + EnableLFS: m.EnableLFS, + EnableOCI: m.EnableOCI, + Proxy: m.Proxy, + NoProxy: m.NoProxy, + Project: m.Project, + ForceHttpBasicAuth: m.ForceHttpBasicAuth, + InheritedCreds: m.InheritedCreds, + GithubAppId: m.GithubAppId, + GithubAppInstallationId: m.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: m.GitHubAppEnterpriseBaseURL, + } +} + +func (m *Repository) Normalize() *Repository { + if m.Type == "" { + m.Type = common.DefaultRepoType + } + return m +} + // Repositories defines a list of Repository configurations type Repositories []*Repository diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 0112ac161782e..5e7e99960c54d 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -3,9 +3,11 @@ package v1alpha1 import ( "encoding/json" "fmt" + "maps" "math" "net" "net/http" + "net/url" "os" "path/filepath" "reflect" @@ -18,6 +20,7 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" + "github.com/argoproj/gitops-engine/pkg/utils/kube" "github.com/robfig/cron/v3" log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" @@ -36,7 +39,6 @@ import ( "sigs.k8s.io/yaml" "github.com/argoproj/argo-cd/v2/common" - "github.com/argoproj/argo-cd/v2/util/collections" "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/helm" utilhttp "github.com/argoproj/argo-cd/v2/util/http" @@ -84,6 +86,9 @@ type ApplicationSpec struct { // Sources is a reference to the location of the application's manifests or chart Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,8,opt,name=sources"` + + // SourceHydrator provides a way to push hydrated manifests back to git before syncing them to the cluster. + SourceHydrator *SourceHydrator `json:"sourceHydrator,omitempty" protobuf:"bytes,9,opt,name=sourceHydrator"` } type IgnoreDifferences []ResourceIgnoreDifferences @@ -189,6 +194,8 @@ type ApplicationSource struct { Chart string `json:"chart,omitempty" protobuf:"bytes,12,opt,name=chart"` // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. Ref string `json:"ref,omitempty" protobuf:"bytes,13,opt,name=ref"` + // Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications. + Name string `json:"name,omitempty" protobuf:"bytes,14,opt,name=name"` } // ApplicationSources contains list of required information about the sources of an application @@ -212,6 +219,9 @@ func (a ApplicationSources) IsZero() bool { } func (a *ApplicationSpec) GetSource() ApplicationSource { + if a.SourceHydrator != nil { + return a.SourceHydrator.GetSyncSource() + } // if Application has multiple sources, return the first source in sources if a.HasMultipleSources() { return a.Sources[0] @@ -222,7 +232,26 @@ func (a *ApplicationSpec) GetSource() ApplicationSource { return ApplicationSource{} } +// GetHydrateToSource returns the hydrateTo source if it exists, otherwise returns the sync source. +func (a *ApplicationSpec) GetHydrateToSource() ApplicationSource { + if a.SourceHydrator != nil { + targetRevision := a.SourceHydrator.SyncSource.TargetBranch + if a.SourceHydrator.HydrateTo != nil { + targetRevision = a.SourceHydrator.HydrateTo.TargetBranch + } + return ApplicationSource{ + RepoURL: a.SourceHydrator.DrySource.RepoURL, + Path: a.SourceHydrator.SyncSource.Path, + TargetRevision: targetRevision, + } + } + return ApplicationSource{} +} + func (a *ApplicationSpec) GetSources() ApplicationSources { + if a.SourceHydrator != nil { + return ApplicationSources{a.SourceHydrator.GetSyncSource()} + } if a.HasMultipleSources() { return a.Sources } @@ -233,7 +262,7 @@ func (a *ApplicationSpec) GetSources() ApplicationSources { } func (a *ApplicationSpec) HasMultipleSources() bool { - return len(a.Sources) > 0 + return a.SourceHydrator == nil && len(a.Sources) > 0 } func (a *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *ApplicationSource { @@ -242,6 +271,10 @@ func (a *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *Applicatio } func (a *ApplicationSpec) GetSourcePtrByIndex(sourceIndex int) *ApplicationSource { + if a.SourceHydrator != nil { + source := a.SourceHydrator.GetSyncSource() + return &source + } // if Application has multiple sources, return the first source in sources if a.HasMultipleSources() { if sourceIndex > 0 { @@ -347,6 +380,82 @@ const ( ApplicationSourceTypePlugin ApplicationSourceType = "Plugin" ) +// SourceHydrator specifies a dry "don't repeat yourself" source for manifests, a sync source from which to sync +// hydrated manifests, and an optional hydrateTo location to act as a "staging" aread for hydrated manifests. +type SourceHydrator struct { + // DrySource specifies where the dry "don't repeat yourself" manifest source lives. + DrySource DrySource `json:"drySource" protobuf:"bytes,1,name=drySource"` + // SyncSource specifies where to sync hydrated manifests from. + SyncSource SyncSource `json:"syncSource" protobuf:"bytes,2,name=syncSource"` + // HydrateTo specifies an optional "staging" location to push hydrated manifests to. An external system would then + // have to move manifests to the SyncSource, e.g. by pull request. + HydrateTo *HydrateTo `json:"hydrateTo,omitempty" protobuf:"bytes,3,opt,name=hydrateTo"` +} + +// GetSyncSource gets the source from which we should sync when a source hydrator is configured. +func (s SourceHydrator) GetSyncSource() ApplicationSource { + return ApplicationSource{ + // Pull the RepoURL from the dry source. The SyncSource's RepoURL is assumed to be the same. + RepoURL: s.DrySource.RepoURL, + Path: s.SyncSource.Path, + TargetRevision: s.SyncSource.TargetBranch, + } +} + +// GetDrySource gets the dry source when a source hydrator is configured. +func (s SourceHydrator) GetDrySource() ApplicationSource { + return ApplicationSource{ + RepoURL: s.DrySource.RepoURL, + Path: s.DrySource.Path, + TargetRevision: s.DrySource.TargetRevision, + } +} + +// DeepEquals returns true if the SourceHydrator is deeply equal to the given SourceHydrator. +func (s SourceHydrator) DeepEquals(hydrator SourceHydrator) bool { + return s.DrySource == hydrator.DrySource && s.SyncSource == hydrator.SyncSource && s.HydrateTo.DeepEquals(hydrator.HydrateTo) +} + +// DrySource specifies a location for dry "don't repeat yourself" manifest source information. +type DrySource struct { + // RepoURL is the URL to the git repository that contains the application manifests + RepoURL string `json:"repoURL" protobuf:"bytes,1,name=repoURL"` + // TargetRevision defines the revision of the source to hydrate + TargetRevision string `json:"targetRevision" protobuf:"bytes,2,name=targetRevision"` + // Path is a directory path within the Git repository where the manifests are located + Path string `json:"path" protobuf:"bytes,3,name=path"` +} + +// SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the +// associated DrySource config in the SourceHydrator. +type SyncSource struct { + // TargetBranch is the branch to which hydrated manifests should be committed + TargetBranch string `json:"targetBranch" protobuf:"bytes,1,name=targetBranch"` + // Path is a directory path within the git repository where hydrated manifests should be committed to and synced + // from. If hydrateTo is set, this is just the path from which hydrated manifests will be synced. + Path string `json:"path" protobuf:"bytes,2,name=path"` +} + +// HydrateTo specifies a location to which hydrated manifests should be pushed as a "staging area" before being moved to +// the SyncSource. The RepoURL and Path are assumed based on the associated SyncSource config in the SourceHydrator. +type HydrateTo struct { + // TargetBranch is the branch to which hydrated manifests should be committed + TargetBranch string `json:"targetBranch" protobuf:"bytes,1,name=targetBranch"` +} + +// DeepEquals returns true if the HydrateTo is deeply equal to the given HydrateTo. +func (in *HydrateTo) DeepEquals(to *HydrateTo) bool { + if in == nil { + return to == nil + } + if to == nil { + // We already know in is not nil. + return false + } + // Compare de-referenced structs. + return *in == *to +} + // RefreshType specifies how to refresh the sources of a given application type RefreshType string @@ -395,6 +504,10 @@ type ApplicationSourceHelm struct { // APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, // Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,13,opt,name=apiVersions"` + // SkipTests skips test manifest installation step (Helm's --skip-tests). + SkipTests bool `json:"skipTests,omitempty" protobuf:"bytes,14,opt,name=skipTests"` + // SkipSchemaValidation skips JSON schema validation (Helm's --skip-schema-validation) + SkipSchemaValidation bool `json:"skipSchemaValidation,omitempty" protobuf:"bytes,15,opt,name=skipSchemaValidation"` } // HelmParameter is a parameter that's passed to helm template during manifest generation @@ -476,7 +589,7 @@ func (in *ApplicationSourceHelm) AddFileParameter(p HelmFileParameter) { // IsZero Returns true if the Helm options in an application source are considered zero func (h *ApplicationSourceHelm) IsZero() bool { - return h == nil || (h.Version == "") && (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && len(h.FileParameters) == 0 && h.ValuesIsEmpty() && !h.PassCredentials && !h.IgnoreMissingValueFiles && !h.SkipCrds && h.KubeVersion == "" && len(h.APIVersions) == 0 && h.Namespace == "" + return h == nil || (h.Version == "") && (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && len(h.FileParameters) == 0 && h.ValuesIsEmpty() && !h.PassCredentials && !h.IgnoreMissingValueFiles && !h.SkipCrds && !h.SkipTests && !h.SkipSchemaValidation && h.KubeVersion == "" && len(h.APIVersions) == 0 && h.Namespace == "" } // KustomizeImage represents a Kustomize image definition in the format [old_image_name=]: @@ -997,6 +1110,14 @@ type ApplicationDestination struct { // nolint:govet isServerInferred bool `json:"-"` + // nolint:govet + isNameInferred bool `json:"-"` +} + +// SetIsServerInferred sets the isServerInferred flag. This is used to allow comparison between two destinations where +// one server is inferred and the other is not. +func (d *ApplicationDestination) SetIsServerInferred(inferred bool) { + d.isServerInferred = inferred } type ResourceHealthLocation string @@ -1035,8 +1156,66 @@ type ApplicationStatus struct { SourceTypes []ApplicationSourceType `json:"sourceTypes,omitempty" protobuf:"bytes,12,opt,name=sourceTypes"` // ControllerNamespace indicates the namespace in which the application controller is located ControllerNamespace string `json:"controllerNamespace,omitempty" protobuf:"bytes,13,opt,name=controllerNamespace"` + // SourceHydrator stores information about the current state of source hydration + SourceHydrator SourceHydratorStatus `json:"sourceHydrator,omitempty" protobuf:"bytes,14,opt,name=sourceHydrator"` +} + +// SourceHydratorStatus contains information about the current state of source hydration +type SourceHydratorStatus struct { + // LastSuccessfulOperation holds info about the most recent successful hydration + LastSuccessfulOperation *SuccessfulHydrateOperation `json:"lastSuccessfulOperation,omitempty" protobuf:"bytes,1,opt,name=lastSuccessfulOperation"` + // CurrentOperation holds the status of the hydrate operation + CurrentOperation *HydrateOperation `json:"currentOperation,omitempty" protobuf:"bytes,2,opt,name=currentOperation"` } +func (a *ApplicationStatus) FindResource(key kube.ResourceKey) (*ResourceStatus, bool) { + for i := range a.Resources { + res := a.Resources[i] + if kube.NewResourceKey(res.Group, res.Kind, res.Namespace, res.Name) == key { + return &res, true + } + } + return nil, false +} + +// HydrateOperation contains information about the most recent hydrate operation +type HydrateOperation struct { + // StartedAt indicates when the hydrate operation started + StartedAt metav1.Time `json:"startedAt,omitempty" protobuf:"bytes,1,opt,name=startedAt"` + // FinishedAt indicates when the hydrate operation finished + FinishedAt *metav1.Time `json:"finishedAt,omitempty" protobuf:"bytes,2,opt,name=finishedAt"` + // Phase indicates the status of the hydrate operation + Phase HydrateOperationPhase `json:"phase" protobuf:"bytes,3,opt,name=phase"` + // Message contains a message describing the current status of the hydrate operation + Message string `json:"message" protobuf:"bytes,4,opt,name=message"` + // DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation + DrySHA string `json:"drySHA,omitempty" protobuf:"bytes,5,opt,name=drySHA"` + // HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation + HydratedSHA string `json:"hydratedSHA,omitempty" protobuf:"bytes,6,opt,name=hydratedSHA"` + // SourceHydrator holds the hydrator config used for the hydrate operation + SourceHydrator SourceHydrator `json:"sourceHydrator,omitempty" protobuf:"bytes,7,opt,name=sourceHydrator"` +} + +// SuccessfulHydrateOperation contains information about the most recent successful hydrate operation +type SuccessfulHydrateOperation struct { + // DrySHA holds the resolved revision (sha) of the dry source as of the most recent reconciliation + DrySHA string `json:"drySHA,omitempty" protobuf:"bytes,5,opt,name=drySHA"` + // HydratedSHA holds the resolved revision (sha) of the hydrated source as of the most recent reconciliation + HydratedSHA string `json:"hydratedSHA,omitempty" protobuf:"bytes,6,opt,name=hydratedSHA"` + // SourceHydrator holds the hydrator config used for the hydrate operation + SourceHydrator SourceHydrator `json:"sourceHydrator,omitempty" protobuf:"bytes,7,opt,name=sourceHydrator"` +} + +// HydrateOperationPhase indicates the status of a hydrate operation +// +kubebuilder:validation:Enum=Hydrating;Failed;Hydrated +type HydrateOperationPhase string + +const ( + HydrateOperationPhaseHydrating HydrateOperationPhase = "Hydrating" + HydrateOperationPhaseFailed HydrateOperationPhase = "Failed" + HydrateOperationPhaseHydrated HydrateOperationPhase = "Hydrated" +) + // GetRevisions will return the current revision associated with the Application. // If app has multisources, it will return all corresponding revisions preserving // order from the app.spec.sources. If app has only one source, it will return a @@ -1053,15 +1232,15 @@ func (a *ApplicationStatus) GetRevisions() []string { // BuildComparedToStatus will build a ComparedTo object based on the current // Application state. -func (app *Application) BuildComparedToStatus() ComparedTo { +func (spec *ApplicationSpec) BuildComparedToStatus() ComparedTo { ct := ComparedTo{ - Destination: app.Spec.Destination, - IgnoreDifferences: app.Spec.IgnoreDifferences, + Destination: spec.Destination, + IgnoreDifferences: spec.IgnoreDifferences, } - if app.Spec.HasMultipleSources() { - ct.Sources = app.Spec.Sources + if spec.HasMultipleSources() { + ct.Sources = spec.Sources } else { - ct.Source = app.Spec.GetSource() + ct.Source = spec.GetSource() } return ct } @@ -1171,6 +1350,8 @@ type SyncOperation struct { // Revisions is the list of revision (Git) or chart version (Helm) which to sync each source in sources field for the application to // If omitted, will use the revision specified in app spec. Revisions []string `json:"revisions,omitempty" protobuf:"bytes,11,opt,name=revisions"` + // SelfHealAttemptsCount contains the number of auto-heal attempts + SelfHealAttemptsCount int64 `json:"autoHealAttemptsCount,omitempty" protobuf:"bytes,12,opt,name=autoHealAttemptsCount"` } // IsApplyStrategy returns true if the sync strategy is "apply" @@ -1593,6 +1774,8 @@ type HealthStatus struct { Status health.HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"` // Message is a human-readable informational message describing the health status Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` + // LastTransitionTime is the time the HealthStatus was set or updated + LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` } // InfoItem contains arbitrary, human readable information about an application @@ -1806,16 +1989,17 @@ func (n *ResourceNode) GroupKindVersion() schema.GroupVersionKind { // ResourceStatus holds the current sync and health status of a resource // TODO: describe members of this type type ResourceStatus struct { - Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` - Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` - Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` - Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` - Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` - Status SyncStatusCode `json:"status,omitempty" protobuf:"bytes,6,opt,name=status"` - Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` - Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` - RequiresPruning bool `json:"requiresPruning,omitempty" protobuf:"bytes,9,opt,name=requiresPruning"` - SyncWave int64 `json:"syncWave,omitempty" protobuf:"bytes,10,opt,name=syncWave"` + Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` + Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"` + Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` + Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"` + Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"` + Status SyncStatusCode `json:"status,omitempty" protobuf:"bytes,6,opt,name=status"` + Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"` + Hook bool `json:"hook,omitempty" protobuf:"bytes,8,opt,name=hook"` + RequiresPruning bool `json:"requiresPruning,omitempty" protobuf:"bytes,9,opt,name=requiresPruning"` + SyncWave int64 `json:"syncWave,omitempty" protobuf:"bytes,10,opt,name=syncWave"` + RequiresDeletionConfirmation bool `json:"requiresDeletionConfirmation,omitempty" protobuf:"bytes,11,opt,name=requiresDeletionConfirmation"` } // GroupVersionKind returns the GVK schema type for given resource status @@ -1935,11 +2119,11 @@ func (c *Cluster) Equals(other *Cluster) bool { return false } - if !collections.StringMapsEqual(c.Annotations, other.Annotations) { + if !maps.Equal(c.Annotations, other.Annotations) { return false } - if !collections.StringMapsEqual(c.Labels, other.Labels) { + if !maps.Equal(c.Labels, other.Labels) { return false } @@ -2035,6 +2219,12 @@ type ClusterConfig struct { // ExecProviderConfig contains configuration for an exec provider ExecProviderConfig *ExecProviderConfig `json:"execProviderConfig,omitempty" protobuf:"bytes,6,opt,name=execProviderConfig"` + + // DisableCompression bypasses automatic GZip compression requests to the server. + DisableCompression bool `json:"disableCompression,omitempty" protobuf:"bytes,7,opt,name=disableCompression"` + + // ProxyURL is the URL to the proxy to be used for all requests send to the server + ProxyUrl string `json:"proxyUrl,omitempty" protobuf:"bytes,8,opt,name=proxyUrl"` } // TLSClientConfig contains settings to enable transport layer security @@ -2379,11 +2569,11 @@ func (s *SyncWindows) HasWindows() bool { } // Active returns a list of sync windows that are currently active -func (s *SyncWindows) Active() *SyncWindows { +func (s *SyncWindows) Active() (*SyncWindows, error) { return s.active(time.Now()) } -func (s *SyncWindows) active(currentTime time.Time) *SyncWindows { +func (s *SyncWindows) active(currentTime time.Time) (*SyncWindows, error) { // If SyncWindows.Active() is called outside of a UTC locale, it should be // first converted to UTC before we scan through the SyncWindows. currentTime = currentTime.In(time.UTC) @@ -2392,8 +2582,14 @@ func (s *SyncWindows) active(currentTime time.Time) *SyncWindows { var active SyncWindows specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) for _, w := range *s { - schedule, _ := specParser.Parse(w.Schedule) - duration, _ := time.ParseDuration(w.Duration) + schedule, sErr := specParser.Parse(w.Schedule) + if sErr != nil { + return nil, fmt.Errorf("cannot parse schedule '%s': %w", w.Schedule, sErr) + } + duration, dErr := time.ParseDuration(w.Duration) + if dErr != nil { + return nil, fmt.Errorf("cannot parse duration '%s': %w", w.Duration, dErr) + } // Offset the nextWindow time to consider the timeZone of the sync window timeZoneOffsetDuration := w.scheduleOffsetByTimeZone() @@ -2403,20 +2599,20 @@ func (s *SyncWindows) active(currentTime time.Time) *SyncWindows { } } if len(active) > 0 { - return &active + return &active, nil } } - return nil + return nil, nil } // InactiveAllows will iterate over the SyncWindows and return all inactive allow windows // for the current time. If the current time is in an inactive allow window, syncs will // be denied. -func (s *SyncWindows) InactiveAllows() *SyncWindows { +func (s *SyncWindows) InactiveAllows() (*SyncWindows, error) { return s.inactiveAllows(time.Now()) } -func (s *SyncWindows) inactiveAllows(currentTime time.Time) *SyncWindows { +func (s *SyncWindows) inactiveAllows(currentTime time.Time) (*SyncWindows, error) { // If SyncWindows.InactiveAllows() is called outside of a UTC locale, it should be // first converted to UTC before we scan through the SyncWindows. currentTime = currentTime.In(time.UTC) @@ -2427,21 +2623,27 @@ func (s *SyncWindows) inactiveAllows(currentTime time.Time) *SyncWindows { for _, w := range *s { if w.Kind == "allow" { schedule, sErr := specParser.Parse(w.Schedule) + if sErr != nil { + return nil, fmt.Errorf("cannot parse schedule '%s': %w", w.Schedule, sErr) + } duration, dErr := time.ParseDuration(w.Duration) + if dErr != nil { + return nil, fmt.Errorf("cannot parse duration '%s': %w", w.Duration, dErr) + } // Offset the nextWindow time to consider the timeZone of the sync window timeZoneOffsetDuration := w.scheduleOffsetByTimeZone() nextWindow := schedule.Next(currentTime.Add(timeZoneOffsetDuration - duration)) - if !nextWindow.Before(currentTime.Add(timeZoneOffsetDuration)) && sErr == nil && dErr == nil { + if !nextWindow.Before(currentTime.Add(timeZoneOffsetDuration)) { inactive = append(inactive, w) } } } if len(inactive) > 0 { - return &inactive + return &inactive, nil } } - return nil + return nil, nil } func (w *SyncWindow) scheduleOffsetByTimeZone() time.Duration { @@ -2545,36 +2747,42 @@ func (w *SyncWindows) Matches(app *Application) *SyncWindows { } // CanSync returns true if a sync window currently allows a sync. isManual indicates whether the sync has been triggered manually. -func (w *SyncWindows) CanSync(isManual bool) bool { +func (w *SyncWindows) CanSync(isManual bool) (bool, error) { if !w.HasWindows() { - return true + return true, nil } - active := w.Active() + active, err := w.Active() + if err != nil { + return false, fmt.Errorf("invalid sync windows: %w", err) + } hasActiveDeny, manualEnabled := active.hasDeny() if hasActiveDeny { if isManual && manualEnabled { - return true + return true, nil } else { - return false + return false, nil } } if active.hasAllow() { - return true + return true, nil } - inactiveAllows := w.InactiveAllows() + inactiveAllows, err := w.InactiveAllows() + if err != nil { + return false, fmt.Errorf("invalid sync windows: %w", err) + } if inactiveAllows.HasWindows() { if isManual && inactiveAllows.manualEnabled() { - return true + return true, nil } else { - return false + return false, nil } } - return true + return true, nil } // hasDeny will iterate over the SyncWindows and return if a deny window is found and if @@ -2629,24 +2837,30 @@ func (w *SyncWindows) manualEnabled() bool { } // Active returns true if the sync window is currently active -func (w SyncWindow) Active() bool { +func (w SyncWindow) Active() (bool, error) { return w.active(time.Now()) } -func (w SyncWindow) active(currentTime time.Time) bool { +func (w SyncWindow) active(currentTime time.Time) (bool, error) { // If SyncWindow.Active() is called outside of a UTC locale, it should be // first converted to UTC before search currentTime = currentTime.UTC() specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - schedule, _ := specParser.Parse(w.Schedule) - duration, _ := time.ParseDuration(w.Duration) + schedule, sErr := specParser.Parse(w.Schedule) + if sErr != nil { + return false, fmt.Errorf("cannot parse schedule '%s': %w", w.Schedule, sErr) + } + duration, dErr := time.ParseDuration(w.Duration) + if dErr != nil { + return false, fmt.Errorf("cannot parse duration '%s': %w", w.Duration, dErr) + } // Offset the nextWindow time to consider the timeZone of the sync window timeZoneOffsetDuration := w.scheduleOffsetByTimeZone() nextWindow := schedule.Next(currentTime.Add(timeZoneOffsetDuration - duration)) - return nextWindow.Before(currentTime.Add(timeZoneOffsetDuration)) + return nextWindow.Before(currentTime.Add(timeZoneOffsetDuration)), nil } // Update updates a sync window's settings with the given parameter @@ -2767,11 +2981,11 @@ type KustomizeOptions struct { // ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation. type ApplicationDestinationServiceAccount struct { // Server specifies the URL of the target cluster's Kubernetes control plane API. - Server string `json:"server,omitempty" protobuf:"bytes,1,opt,name=server"` + Server string `json:"server" protobuf:"bytes,1,opt,name=server"` // Namespace specifies the target namespace for the application's resources. Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"` - // ServiceAccountName to be used for impersonation during the sync operation - DefaultServiceAccount string `json:"defaultServiceAccount,omitempty" protobuf:"bytes,3,opt,name=defaultServiceAccount"` + // DefaultServiceAccount to be used for impersonation during the sync operation + DefaultServiceAccount string `json:"defaultServiceAccount" protobuf:"bytes,3,opt,name=defaultServiceAccount"` } // CascadedDeletion indicates if the deletion finalizer is set and controller should delete the application and it's cascaded resources @@ -2802,6 +3016,22 @@ func (app *Application) IsRefreshRequested() (RefreshType, bool) { return refreshType, true } +// IsHydrateRequested returns whether hydration has been requested for an application +func (app *Application) IsHydrateRequested() bool { + annotations := app.GetAnnotations() + if annotations == nil { + return false + } + typeStr, ok := annotations[AnnotationKeyHydrate] + if !ok { + return false + } + if typeStr == "normal" { + return true + } + return false +} + func (app *Application) HasPostDeleteFinalizer(stage ...string) bool { return getFinalizerIndex(app.ObjectMeta, strings.Join(append([]string{PostDeleteFinalizerName}, stage...), "/")) > -1 } @@ -2995,6 +3225,17 @@ func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { other.Server = "" other.isServerInferred = false } + + if dest.isNameInferred { + dest.Name = "" + dest.isNameInferred = false + } + + if other.isNameInferred { + other.Name = "" + other.isNameInferred = false + } + return reflect.DeepEqual(dest, other) } @@ -3074,6 +3315,9 @@ func SetK8SConfigDefaults(config *rest.Config) error { DisableCompression: config.DisableCompression, IdleConnTimeout: K8sTCPIdleConnTimeout, }) + if config.Proxy != nil { + transport.Proxy = config.Proxy + } tr, err := rest.HTTPWrappersForConfig(config, transport) if err != nil { return err @@ -3097,8 +3341,22 @@ func SetK8SConfigDefaults(config *rest.Config) error { return nil } +// ParseProxyUrl returns a parsed url and verifies that schema is correct +func ParseProxyUrl(proxyUrl string) (*url.URL, error) { + u, err := url.Parse(proxyUrl) + if err != nil { + return nil, err + } + switch u.Scheme { + case "http", "https", "socks5": + default: + return nil, fmt.Errorf("Failed to parse proxy url, unsupported scheme %q, must be http, https, or socks5", u.Scheme) + } + return u, nil +} + // RawRestConfig returns a go-client REST config from cluster that might be serialized into the file using kube.WriteKubeConfig method. -func (c *Cluster) RawRestConfig() *rest.Config { +func (c *Cluster) RawRestConfig() (*rest.Config, error) { var config *rest.Config var err error if c.Server == KubernetesInternalAPIServerAddr && env.ParseBoolFromEnv(EnvVarFakeInClusterConfig, false) { @@ -3182,22 +3440,33 @@ func (c *Cluster) RawRestConfig() *rest.Config { } } if err != nil { - panic(fmt.Sprintf("Unable to create K8s REST config: %v", err)) + return nil, fmt.Errorf("Unable to create K8s REST config: %w", err) + } + if c.Config.ProxyUrl != "" { + u, err := ParseProxyUrl(c.Config.ProxyUrl) + if err != nil { + return nil, fmt.Errorf("Unable to create K8s REST config, can`t parse proxy url: %w", err) + } + config.Proxy = http.ProxyURL(u) } + config.DisableCompression = c.Config.DisableCompression config.Timeout = K8sServerSideTimeout config.QPS = K8sClientConfigQPS config.Burst = K8sClientConfigBurst - return config + return config, nil } // RESTConfig returns a go-client REST config from cluster with tuned throttling and HTTP client settings. -func (c *Cluster) RESTConfig() *rest.Config { - config := c.RawRestConfig() - err := SetK8SConfigDefaults(config) +func (c *Cluster) RESTConfig() (*rest.Config, error) { + config, err := c.RawRestConfig() if err != nil { - panic(fmt.Sprintf("Unable to apply K8s REST config defaults: %v", err)) + return nil, fmt.Errorf("Unable to get K8s RAW REST config: %w", err) } - return config + err = SetK8SConfigDefaults(config) + if err != nil { + return nil, fmt.Errorf("Unable to apply K8s REST config defaults: %w", err) + } + return config, nil } // UnmarshalToUnstructured unmarshals a resource representation in JSON to unstructured data @@ -3229,6 +3498,12 @@ func (d *ApplicationDestination) SetInferredServer(server string) { d.Server = server } +// SetInferredName sets the Name field of the destination. See IsNameInferred() for details. +func (d *ApplicationDestination) SetInferredName(name string) { + d.isNameInferred = true + d.Name = name +} + // An ApplicationDestination has an 'inferred server' if the ApplicationDestination // contains a Name, but not a Server URL. In this case it is necessary to retrieve // the Server URL by looking up the cluster name. @@ -3239,6 +3514,10 @@ func (d *ApplicationDestination) IsServerInferred() bool { return d.isServerInferred } +func (d *ApplicationDestination) IsNameInferred() bool { + return d.isNameInferred +} + // MarshalJSON marshals an application destination to JSON format func (d *ApplicationDestination) MarshalJSON() ([]byte, error) { type Alias ApplicationDestination @@ -3247,6 +3526,11 @@ func (d *ApplicationDestination) MarshalJSON() ([]byte, error) { dest = dest.DeepCopy() dest.Server = "" } + if d.isNameInferred { + dest = dest.DeepCopy() + dest.Name = "" + } + return json.Marshal(&struct{ *Alias }{Alias: (*Alias)(dest)}) } @@ -3279,3 +3563,27 @@ func (a *Application) QualifiedName() string { func (a *Application) RBACName(defaultNS string) string { return security.RBACName(defaultNS, a.Spec.GetProject(), a.Namespace, a.Name) } + +// GetAnnotation returns the value of the specified annotation if it exists, +// e.g., a.GetAnnotation("argocd.argoproj.io/manifest-generate-paths"). +// If the annotation does not exist, it returns an empty string. +func (a *Application) GetAnnotation(annotation string) string { + v, exists := a.Annotations[annotation] + if !exists { + return "" + } + + return v +} + +func (a *Application) IsDeletionConfirmed(since time.Time) bool { + val := a.GetAnnotation(synccommon.AnnotationDeletionApproved) + if val == "" { + return false + } + parsedVal, err := time.Parse(time.RFC3339, val) + if err != nil { + return false + } + return parsedVal.After(since) || parsedVal.Equal(since) +} diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index 08b83c238a93d..1d29219d05d9e 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -107,12 +107,16 @@ func TestAppProject_IsNegatedSourcePermitted(t *testing.T) { } func TestAppProject_IsDestinationPermitted(t *testing.T) { + t.Parallel() + testData := []struct { + name string projDest []ApplicationDestination appDest ApplicationDestination isPermitted bool }{ { + name: "server an namespace match", projDest: []ApplicationDestination{{ Server: "https://kubernetes.default.svc", Namespace: "default", }}, @@ -120,6 +124,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "namespace does not match", projDest: []ApplicationDestination{{ Server: "https://kubernetes.default.svc", Namespace: "default", }}, @@ -127,6 +132,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: false, }, { + name: "server does not match", projDest: []ApplicationDestination{{ Server: "https://my-cluster", Namespace: "default", }}, @@ -134,6 +140,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: false, }, { + name: "wildcard namespace", projDest: []ApplicationDestination{{ Server: "https://kubernetes.default.svc", Namespace: "*", }}, @@ -141,6 +148,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "wildcard server", projDest: []ApplicationDestination{{ Server: "https://*.default.svc", Namespace: "default", }}, @@ -148,6 +156,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "wildcard server and namespace", projDest: []ApplicationDestination{{ Server: "https://team1-*", Namespace: "default", }}, @@ -155,6 +164,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: false, }, { + name: "wildcard namespace with prefix", projDest: []ApplicationDestination{{ Server: "https://kubernetes.default.svc", Namespace: "test-*", }}, @@ -162,6 +172,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "wildcard namespace without prefix", projDest: []ApplicationDestination{{ Server: "https://kubernetes.default.svc", Namespace: "test-*", }}, @@ -169,6 +180,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: false, }, { + name: "wildcard server and namespace", projDest: []ApplicationDestination{{ Server: "*", Namespace: "*", }}, @@ -176,6 +188,7 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "wildcard server and namespace with name", projDest: []ApplicationDestination{{ Server: "", Namespace: "*", Name: "test", }}, @@ -183,24 +196,51 @@ func TestAppProject_IsDestinationPermitted(t *testing.T) { isPermitted: true, }, { + name: "wildcard server and namespace with different name", projDest: []ApplicationDestination{{ Server: "", Namespace: "*", Name: "test2", }}, appDest: ApplicationDestination{Name: "test", Namespace: "test"}, isPermitted: false, }, + /** + - name: host-cluster + namespace: '!{kube-system,argocd}' + server: 'https://kubernetes.default.svc' + - name: destination-cluster-01 + namespace: '*' + server: 'https://eks-cluster-endpoint.ap-southeast-1.eks.amazonaws.com' + + destination: + server: https://eks-cluster-endpoint.ap-southeast-1.eks.amazonaws.com + namespace: karpenter + */ + { + name: "negated namespace with multiple values", + projDest: []ApplicationDestination{ + {Name: "host-cluster", Server: "https://kubernetes.default.svc", Namespace: "!{kube-system,argocd}"}, + {Name: "destination-cluster-01", Server: "https://eks-cluster-endpoint.ap-southeast-1.eks.amazonaws.com", Namespace: "*"}, + }, + appDest: ApplicationDestination{Server: "https://eks-cluster-endpoint.ap-southeast-1.eks.amazonaws.com", Namespace: "kube-system"}, + isPermitted: true, + }, } for _, data := range testData { - proj := AppProject{ - Spec: AppProjectSpec{ - Destinations: data.projDest, - }, - } - permitted, _ := proj.IsDestinationPermitted(data.appDest, func(project string) ([]*Cluster, error) { - return []*Cluster{}, nil + data := data + t.Run(data.name, func(t *testing.T) { + t.Parallel() + + proj := AppProject{ + Spec: AppProjectSpec{ + Destinations: data.projDest, + }, + } + permitted, _ := proj.IsDestinationPermitted(data.appDest, func(project string) ([]*Cluster, error) { + return []*Cluster{}, nil + }) + assert.Equal(t, data.isPermitted, permitted) }) - assert.Equal(t, data.isPermitted, permitted) } } @@ -320,7 +360,7 @@ func TestAppProject_IsNegatedDestinationPermitted(t *testing.T) { Server: "*", Namespace: "!kube-system", }}, appDest: ApplicationDestination{Server: "https://kubernetes.default.svc", Namespace: "default"}, - isPermitted: false, + isPermitted: true, }, { projDest: []ApplicationDestination{{ Server: "*", Namespace: "*", @@ -339,6 +379,22 @@ func TestAppProject_IsNegatedDestinationPermitted(t *testing.T) { }}, appDest: ApplicationDestination{Name: "test", Namespace: "test"}, isPermitted: false, + }, { + projDest: []ApplicationDestination{{ + Server: "*", Namespace: "test", + }, { + Server: "!https://test-server", Namespace: "other", + }}, + appDest: ApplicationDestination{Server: "https://test-server", Namespace: "test"}, + isPermitted: true, + }, { + projDest: []ApplicationDestination{{ + Server: "*", Namespace: "*", + }, { + Server: "https://test-server", Namespace: "!other", + }}, + appDest: ApplicationDestination{Server: "https://other-test-server", Namespace: "other"}, + isPermitted: true, }} for _, data := range testData { @@ -350,7 +406,7 @@ func TestAppProject_IsNegatedDestinationPermitted(t *testing.T) { permitted, _ := proj.IsDestinationPermitted(data.appDest, func(project string) ([]*Cluster, error) { return []*Cluster{}, nil }) - assert.Equal(t, data.isPermitted, permitted) + assert.Equalf(t, data.isPermitted, permitted, "appDest mismatch for %+v with project destinations %+v", data.appDest, data.projDest) } } @@ -438,8 +494,7 @@ func TestAppProject_IsDestinationPermitted_PermitOnlyProjectScopedClusters(t *te _, err := proj.IsDestinationPermitted(ApplicationDestination{Server: "https://my-cluster.123.com", Namespace: "default"}, func(_ string) ([]*Cluster, error) { return nil, errors.New("some error") }) - require.Error(t, err) - assert.Contains(t, err.Error(), "could not retrieve project clusters") + assert.ErrorContains(t, err, "could not retrieve project clusters") } func TestAppProject_IsGroupKindPermitted(t *testing.T) { @@ -801,8 +856,7 @@ func TestAppProject_InvalidPolicyRules(t *testing.T) { for _, bad := range badPolicies { p.Spec.Roles[0].Policies = []string{bad.policy} err = p.ValidateProject() - require.Error(t, err) - assert.Contains(t, err.Error(), bad.errmsg) + assert.ErrorContains(t, err, bad.errmsg) } } @@ -1778,7 +1832,9 @@ func TestSyncWindows_HasWindows(t *testing.T) { func TestSyncWindows_Active(t *testing.T) { t.Run("WithTestProject", func(t *testing.T) { proj := newTestProjectWithSyncWindows() - assert.Len(t, *proj.Spec.SyncWindows.Active(), 1) + activeWindows, err := proj.Spec.SyncWindows.Active() + require.NoError(t, err) + assert.Len(t, *activeWindows, 1) }) syncWindow := func(kind string, schedule string, duration string, timeZone string) *SyncWindow { @@ -1805,6 +1861,7 @@ func TestSyncWindows_Active(t *testing.T) { currentTime time.Time matchingIndex int expectedLength int + isErr bool }{ { name: "MatchFirst", @@ -1912,11 +1969,36 @@ func TestSyncWindows_Active(t *testing.T) { matchingIndex: 0, expectedLength: 1, }, + { + name: "MatchNone-InvalidSchedule", + syncWindow: SyncWindows{ + syncWindow("allow", "* 10 * * 7", "3h", ""), + syncWindow("allow", "* 11 * * 7", "3h", ""), + }, + currentTime: timeWithHour(12, time.UTC), + expectedLength: 0, + isErr: true, + }, + { + name: "MatchNone-InvalidDuration", + syncWindow: SyncWindows{ + syncWindow("allow", "* 10 * * *", "3a", ""), + syncWindow("allow", "* 11 * * *", "3a", ""), + }, + currentTime: timeWithHour(12, time.UTC), + expectedLength: 0, + isErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := tt.syncWindow.active(tt.currentTime) + result, err := tt.syncWindow.active(tt.currentTime) + if tt.isErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } if result == nil { result = &SyncWindows{} } @@ -1933,7 +2015,9 @@ func TestSyncWindows_InactiveAllows(t *testing.T) { t.Run("WithTestProject", func(t *testing.T) { proj := newTestProjectWithSyncWindows() proj.Spec.SyncWindows[0].Schedule = "0 0 1 1 1" - assert.Len(t, *proj.Spec.SyncWindows.InactiveAllows(), 1) + inactiveAllowWindows, err := proj.Spec.SyncWindows.InactiveAllows() + require.NoError(t, err) + assert.Len(t, *inactiveAllowWindows, 1) }) syncWindow := func(kind string, schedule string, duration string, timeZone string) *SyncWindow { @@ -1960,6 +2044,7 @@ func TestSyncWindows_InactiveAllows(t *testing.T) { currentTime time.Time matchingIndex int expectedLength int + isErr bool }{ { name: "MatchFirst", @@ -2085,11 +2170,34 @@ func TestSyncWindows_InactiveAllows(t *testing.T) { matchingIndex: 0, expectedLength: 1, }, + { + name: "MatchNone-InvalidSchedule", + syncWindow: SyncWindows{ + syncWindow("allow", "* 10 * * 7", "2h", ""), + }, + currentTime: timeWithHour(17, time.UTC), + expectedLength: 0, + isErr: true, + }, + { + name: "MatchNone-InvalidDuration", + syncWindow: SyncWindows{ + syncWindow("allow", "* 10 * * *", "2a", ""), + }, + currentTime: timeWithHour(17, time.UTC), + expectedLength: 0, + isErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := tt.syncWindow.inactiveAllows(tt.currentTime) + result, err := tt.syncWindow.inactiveAllows(tt.currentTime) + if tt.isErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } if result == nil { result = &SyncWindows{} } @@ -2200,9 +2308,10 @@ func TestSyncWindows_CanSync(t *testing.T) { proj := newProjectBuilder().withInactiveDenyWindow(true).build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will allow manual sync if inactive-deny-window set with manual false", func(t *testing.T) { @@ -2211,9 +2320,10 @@ func TestSyncWindows_CanSync(t *testing.T) { proj := newProjectBuilder().withInactiveDenyWindow(false).build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny manual sync if one inactive-allow-windows set with manual false", func(t *testing.T) { @@ -2225,9 +2335,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will allow manual sync if on active-allow-window set with manual true", func(t *testing.T) { @@ -2238,9 +2349,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will allow manual sync if on active-allow-window set with manual false", func(t *testing.T) { @@ -2251,9 +2363,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will allow auto sync if on active-allow-window", func(t *testing.T) { @@ -2264,9 +2377,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will allow manual sync active-allow and inactive-deny", func(t *testing.T) { @@ -2278,9 +2392,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will allow auto sync active-allow and inactive-deny", func(t *testing.T) { @@ -2292,9 +2407,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny manual sync inactive-allow", func(t *testing.T) { @@ -2305,9 +2421,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny auto sync inactive-allow", func(t *testing.T) { @@ -2318,9 +2435,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will allow manual sync inactive-allow with ManualSync enabled", func(t *testing.T) { @@ -2331,9 +2449,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny auto sync inactive-allow with ManualSync enabled", func(t *testing.T) { @@ -2344,9 +2463,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny manual sync with inactive-allow and inactive-deny", func(t *testing.T) { @@ -2358,9 +2478,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny auto sync with inactive-allow and inactive-deny", func(t *testing.T) { @@ -2372,9 +2493,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will allow auto sync with active-allow and inactive-allow", func(t *testing.T) { @@ -2386,9 +2508,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny manual sync with active-deny", func(t *testing.T) { @@ -2399,9 +2522,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny auto sync with active-deny", func(t *testing.T) { @@ -2412,9 +2536,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will allow manual sync with active-deny with ManualSync enabled", func(t *testing.T) { @@ -2425,9 +2550,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny auto sync with active-deny with ManualSync enabled", func(t *testing.T) { @@ -2438,9 +2564,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny manual sync with many active-deny having one with ManualSync disabled", func(t *testing.T) { @@ -2454,9 +2581,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny auto sync with many active-deny having one with ManualSync disabled", func(t *testing.T) { @@ -2470,9 +2598,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will deny manual sync with active-deny and active-allow windows with ManualSync disabled", func(t *testing.T) { @@ -2484,9 +2613,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.False(t, canSync) }) t.Run("will allow manual sync with active-deny and active-allow windows with ManualSync enabled", func(t *testing.T) { @@ -2498,9 +2628,10 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(true) + canSync, err := proj.Spec.SyncWindows.CanSync(true) // then + require.NoError(t, err) assert.True(t, canSync) }) t.Run("will deny auto sync with active-deny and active-allow windows with ManualSync enabled", func(t *testing.T) { @@ -2512,9 +2643,24 @@ func TestSyncWindows_CanSync(t *testing.T) { build() // when - canSync := proj.Spec.SyncWindows.CanSync(false) + canSync, err := proj.Spec.SyncWindows.CanSync(false) // then + require.NoError(t, err) + assert.False(t, canSync) + }) + t.Run("will deny and return error with invalid windows", func(t *testing.T) { + // given + t.Parallel() + proj := newProjectBuilder(). + withInvalidWindows(). + build() + + // when + canSync, err := proj.Spec.SyncWindows.CanSync(false) + + // then + require.Error(t, err) assert.False(t, canSync) }) } @@ -2564,8 +2710,9 @@ func TestSyncWindows_hasAllow(t *testing.T) { func TestSyncWindow_Active(t *testing.T) { window := &SyncWindow{Schedule: "* * * * *", Duration: "1h"} t.Run("ActiveWindow", func(t *testing.T) { - window.Active() - assert.True(t, window.Active()) + isActive, err := window.Active() + require.NoError(t, err) + assert.True(t, isActive) }) syncWindow := func(kind string, schedule string, duration string) SyncWindow { @@ -2590,6 +2737,7 @@ func TestSyncWindow_Active(t *testing.T) { syncWindow SyncWindow currentTime time.Time expectedResult bool + isErr bool }{ { name: "Allow-active", @@ -2639,11 +2787,44 @@ func TestSyncWindow_Active(t *testing.T) { currentTime: timeWithHour(13-4, utcM4Zone), expectedResult: false, }, + { + name: "Allow-inactive-InvalidSchedule", + syncWindow: syncWindow("allow", "* 10 * * 7", "2h"), + currentTime: timeWithHour(11, time.UTC), + expectedResult: false, + isErr: true, + }, + { + name: "Deny-inactive-InvalidSchedule", + syncWindow: syncWindow("deny", "* 10 * * 7", "2h"), + currentTime: timeWithHour(11, time.UTC), + expectedResult: false, + isErr: true, + }, + { + name: "Allow-inactive-InvalidDuration", + syncWindow: syncWindow("allow", "* 10 * * *", "2a"), + currentTime: timeWithHour(11, time.UTC), + expectedResult: false, + isErr: true, + }, + { + name: "Deny-inactive-InvalidDuration", + syncWindow: syncWindow("deny", "* 10 * * *", "2a"), + currentTime: timeWithHour(11, time.UTC), + expectedResult: false, + isErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := tt.syncWindow.active(tt.currentTime) + result, err := tt.syncWindow.active(tt.currentTime) + if tt.isErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } assert.Equal(t, tt.expectedResult, result) }) } @@ -2755,6 +2936,16 @@ func (b *projectBuilder) withInactiveDenyWindow(allowManual bool) *projectBuilde return b } +func (b *projectBuilder) withInvalidWindows() *projectBuilder { + b.proj.Spec.SyncWindows = append(b.proj.Spec.SyncWindows, + newSyncWindow("allow", "* 10 * * 7", false), + newSyncWindow("deny", "* 10 * * 7", false), + newSyncWindow("allow", "* 10 * * 7", true), + newSyncWindow("deny", "* 10 * * 7", true), + ) + return b +} + func inactiveCronSchedule() string { hourPlus10, _, _ := time.Now().Add(10 * time.Hour).Clock() return fmt.Sprintf("0 %d * * *", hourPlus10) @@ -2831,6 +3022,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar", tenMinsAgo), }, validate: func(t *testing.T, a *Application) { + t.Helper() assert.Equal(t, fiveMinsAgo, a.Status.Conditions[0].LastTransitionTime) assert.Equal(t, tenMinsAgo, a.Status.Conditions[1].LastTransitionTime) }, @@ -2851,6 +3043,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar", nil), }, validate: func(t *testing.T, a *Application) { + t.Helper() // SetConditions should add timestamps for new conditions. assert.True(t, a.Status.Conditions[0].LastTransitionTime.Time.After(fiveMinsAgo.Time)) assert.True(t, a.Status.Conditions[1].LastTransitionTime.Time.After(fiveMinsAgo.Time)) @@ -2873,6 +3066,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar", tenMinsAgo), }, validate: func(t *testing.T, a *Application) { + t.Helper() assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[0].LastTransitionTime.Time) }, }, @@ -2908,6 +3102,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar", tenMinsAgo), }, validate: func(t *testing.T, a *Application) { + t.Helper() assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[0].LastTransitionTime.Time) assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[1].LastTransitionTime.Time) }, @@ -2931,6 +3126,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar changed message", fiveMinsAgo), }, validate: func(t *testing.T, a *Application) { + t.Helper() assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[0].LastTransitionTime.Time) assert.Equal(t, fiveMinsAgo.Time, a.Status.Conditions[1].LastTransitionTime.Time) }, @@ -2949,6 +3145,7 @@ func TestSetConditions(t *testing.T) { testCond(ApplicationConditionSharedResourceWarning, "bar", tenMinsAgo), }, validate: func(t *testing.T, a *Application) { + t.Helper() assert.Equal(t, tenMinsAgo.Time, a.Status.Conditions[0].LastTransitionTime.Time) }, }, @@ -2970,6 +3167,7 @@ func TestSetConditions(t *testing.T) { // difficult to strictly assert on as they can use time.Now(). Elements in each array are assumed // to match positions. func assertConditions(t *testing.T, expected []ApplicationCondition, actual []ApplicationCondition) { + t.Helper() assert.Equal(t, len(expected), len(actual)) for i := range expected { assert.Equal(t, expected[i].Type, actual[i].Type) @@ -3765,6 +3963,7 @@ func TestOptionalArrayEquality(t *testing.T) { err := json.Unmarshal([]byte(presentButEmpty), ¶m) require.NoError(t, err) jsonPresentButEmpty := param.OptionalArray + // nolint:testifylint require.Equal(t, &OptionalArray{Array: []string{}}, jsonPresentButEmpty) // We won't simulate the protobuf unmarshalling of an empty array parameter. By experimentation, this is how it's @@ -3808,6 +4007,7 @@ func TestOptionalMapEquality(t *testing.T) { err := json.Unmarshal([]byte(presentButEmpty), ¶m) require.NoError(t, err) jsonPresentButEmpty := param.OptionalMap + // nolint:testifylint require.Equal(t, &OptionalMap{Map: map[string]string{}}, jsonPresentButEmpty) // We won't simulate the protobuf unmarshalling of an empty map parameter. By experimentation, this is how it's @@ -3959,3 +4159,190 @@ func TestApplicationTree_Merge(t *testing.T) { }, }, tree) } + +func TestAppProject_ValidateDestinationServiceAccount(t *testing.T) { + testData := []struct { + server string + namespace string + defaultServiceAccount string + expectedErrMsg string + }{ + { + // Given, a project + // When, a default destination service account with all valid fields is added to it, + // Then, there is no error. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "test-sa", + expectedErrMsg: "", + }, + { + // Given, a project + // When, a default destination service account with negation glob pattern for server is added, + // Then, there is an error with appropriate message. + server: "!abc", + namespace: "test-ns", + defaultServiceAccount: "test-sa", + expectedErrMsg: "server has an invalid format, '!abc'", + }, + { + // Given, a project + // When, a default destination service account with empty namespace is added to it, + // Then, there is no error. + server: "https://192.168.99.100:8443", + namespace: "", + defaultServiceAccount: "test-sa", + expectedErrMsg: "", + }, + { + // Given, a project, + // When, a default destination service account with negation glob pattern for server is added, + // Then, there is an error with appropriate message. + server: "!*", + namespace: "test-ns", + defaultServiceAccount: "test-sa", + expectedErrMsg: "server has an invalid format, '!*'", + }, + { + // Given, a project, + // When, a default destination service account with negation glob pattern for namespace is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "!*", + defaultServiceAccount: "test-sa", + expectedErrMsg: "namespace has an invalid format, '!*'", + }, + { + // Given, a project, + // When, a default destination service account with negation glob pattern for namespace is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "!abc", + defaultServiceAccount: "test-sa", + expectedErrMsg: "namespace has an invalid format, '!abc'", + }, + { + // Given, a project, + // When, a default destination service account with empty service account is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "", + expectedErrMsg: "defaultServiceAccount has an invalid format, ''", + }, + { + // Given, a project, + // When, a default destination service account with service account having just white spaces is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: " ", + expectedErrMsg: "defaultServiceAccount has an invalid format, ' '", + }, + { + // Given, a project, + // When, a default destination service account with service account having backwards slash char is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "test\\sa", + expectedErrMsg: "defaultServiceAccount has an invalid format, 'test\\sa'", + }, + { + // Given, a project, + // When, a default destination service account with service account having forward slash char is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "test/sa", + expectedErrMsg: "defaultServiceAccount has an invalid format, 'test/sa'", + }, + { + // Given, a project, + // When, a default destination service account with service account having square braces char is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "[test-sa]", + expectedErrMsg: "defaultServiceAccount has an invalid format, '[test-sa]'", + }, + { + // Given, a project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "test-ns", + defaultServiceAccount: "{test-sa}", + expectedErrMsg: "defaultServiceAccount has an invalid format, '{test-sa}'", + }, + { + // Given, a project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + server: "[[ech*", + namespace: "test-ns", + defaultServiceAccount: "test-sa", + expectedErrMsg: "server has an invalid format, '[[ech*'", + }, + { + // Given, a project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + server: "https://192.168.99.100:8443", + namespace: "[[ech*", + defaultServiceAccount: "test-sa", + expectedErrMsg: "namespace has an invalid format, '[[ech*'", + }, + } + for _, data := range testData { + proj := AppProject{ + Spec: AppProjectSpec{ + DestinationServiceAccounts: []ApplicationDestinationServiceAccount{ + { + Server: data.server, + Namespace: data.namespace, + DefaultServiceAccount: data.defaultServiceAccount, + }, + }, + }, + } + err := proj.ValidateProject() + if data.expectedErrMsg == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, data.expectedErrMsg) + } + } +} + +func TestCluster_ParseProxyUrl(t *testing.T) { + testData := []struct { + url string + expectedErrMsg string + }{ + { + url: "https://192.168.99.100:8443", + expectedErrMsg: "", + }, + { + url: "test://!abc", + expectedErrMsg: "Failed to parse proxy url, unsupported scheme \"test\", must be http, https, or socks5", + }, + { + url: "http://192.168.99.100:8443", + expectedErrMsg: "", + }, + { + url: "socks5://192.168.99.100:8443", + expectedErrMsg: "", + }, + } + for _, data := range testData { + _, err := ParseProxyUrl(data.url) + if data.expectedErrMsg == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, data.expectedErrMsg) + } + } +} diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 7e1d69473b067..9faf5d3a73b00 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -1,6 +1,19 @@ //go:build !ignore_autogenerated // +build !ignore_autogenerated +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ // Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 @@ -1086,6 +1099,11 @@ func (in *ApplicationSourceHelm) DeepCopyInto(out *ApplicationSourceHelm) { *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } + if in.APIVersions != nil { + in, out := &in.APIVersions, &out.APIVersions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -1169,6 +1187,11 @@ func (in *ApplicationSourceKustomize) DeepCopyInto(out *ApplicationSourceKustomi *out = make([]string, len(*in)) copy(*out, *in) } + if in.APIVersions != nil { + in, out := &in.APIVersions, &out.APIVersions + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -1329,6 +1352,11 @@ func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.SourceHydrator != nil { + in, out := &in.SourceHydrator, &out.SourceHydrator + *out = new(SourceHydrator) + (*in).DeepCopyInto(*out) + } return } @@ -1353,7 +1381,7 @@ func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) { } } in.Sync.DeepCopyInto(&out.Sync) - out.Health = in.Health + in.Health.DeepCopyInto(&out.Health) if in.History != nil { in, out := &in.History, &out.History *out = make(RevisionHistories, len(*in)) @@ -1387,6 +1415,7 @@ func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) { *out = make([]ApplicationSourceType, len(*in)) copy(*out, *in) } + in.SourceHydrator.DeepCopyInto(&out.SourceHydrator) return } @@ -1522,6 +1551,27 @@ func (in *BasicAuthBitbucketServer) DeepCopy() *BasicAuthBitbucketServer { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BearerTokenBitbucket) DeepCopyInto(out *BearerTokenBitbucket) { + *out = *in + if in.TokenRef != nil { + in, out := &in.TokenRef, &out.TokenRef + *out = new(SecretRef) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BearerTokenBitbucket. +func (in *BearerTokenBitbucket) DeepCopy() *BearerTokenBitbucket { + if in == nil { + return nil + } + out := new(BearerTokenBitbucket) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BearerTokenBitbucketCloud) DeepCopyInto(out *BearerTokenBitbucketCloud) { *out = *in @@ -1826,6 +1876,22 @@ func (in *ConfigManagementPlugin) DeepCopy() *ConfigManagementPlugin { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapKeyRef) DeepCopyInto(out *ConfigMapKeyRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapKeyRef. +func (in *ConfigMapKeyRef) DeepCopy() *ConfigMapKeyRef { + if in == nil { + return nil + } + out := new(ConfigMapKeyRef) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConnectionState) DeepCopyInto(out *ConnectionState) { *out = *in @@ -1846,6 +1912,22 @@ func (in *ConnectionState) DeepCopy() *ConnectionState { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DrySource) DeepCopyInto(out *DrySource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DrySource. +func (in *DrySource) DeepCopy() *DrySource { + if in == nil { + return nil + } + out := new(DrySource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DuckTypeGenerator) DeepCopyInto(out *DuckTypeGenerator) { *out = *in @@ -2074,6 +2156,10 @@ func (in *GnuPGPublicKeyList) DeepCopy() *GnuPGPublicKeyList { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { *out = *in + if in.LastTransitionTime != nil { + in, out := &in.LastTransitionTime, &out.LastTransitionTime + *out = (*in).DeepCopy() + } return } @@ -2178,6 +2264,44 @@ func (in *HostResourceInfo) DeepCopy() *HostResourceInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HydrateOperation) DeepCopyInto(out *HydrateOperation) { + *out = *in + in.StartedAt.DeepCopyInto(&out.StartedAt) + if in.FinishedAt != nil { + in, out := &in.FinishedAt, &out.FinishedAt + *out = (*in).DeepCopy() + } + in.SourceHydrator.DeepCopyInto(&out.SourceHydrator) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HydrateOperation. +func (in *HydrateOperation) DeepCopy() *HydrateOperation { + if in == nil { + return nil + } + out := new(HydrateOperation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HydrateTo) DeepCopyInto(out *HydrateTo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HydrateTo. +func (in *HydrateTo) DeepCopy() *HydrateTo { + if in == nil { + return nil + } + out := new(HydrateTo) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in IgnoreDifferences) DeepCopyInto(out *IgnoreDifferences) { { @@ -3068,6 +3192,16 @@ func (in *PullRequestGeneratorBitbucketServer) DeepCopyInto(out *PullRequestGene *out = new(BasicAuthBitbucketServer) (*in).DeepCopyInto(*out) } + if in.BearerToken != nil { + in, out := &in.BearerToken, &out.BearerToken + *out = new(BearerTokenBitbucket) + (*in).DeepCopyInto(*out) + } + if in.CARef != nil { + in, out := &in.CARef, &out.CARef + *out = new(ConfigMapKeyRef) + **out = **in + } return } @@ -3120,6 +3254,11 @@ func (in *PullRequestGeneratorGitLab) DeepCopyInto(out *PullRequestGeneratorGitL *out = make([]string, len(*in)) copy(*out, *in) } + if in.CARef != nil { + in, out := &in.CARef, &out.CARef + *out = new(ConfigMapKeyRef) + **out = **in + } return } @@ -3576,7 +3715,7 @@ func (in *ResourceNode) DeepCopyInto(out *ResourceNode) { if in.Health != nil { in, out := &in.Health, &out.Health *out = new(HealthStatus) - **out = **in + (*in).DeepCopyInto(*out) } if in.CreatedAt != nil { in, out := &in.CreatedAt, &out.CreatedAt @@ -3682,7 +3821,7 @@ func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) { if in.Health != nil { in, out := &in.Health, &out.Health *out = new(HealthStatus) - **out = **in + (*in).DeepCopyInto(*out) } return } @@ -3945,6 +4084,16 @@ func (in *SCMProviderGeneratorBitbucketServer) DeepCopyInto(out *SCMProviderGene *out = new(BasicAuthBitbucketServer) (*in).DeepCopyInto(*out) } + if in.BearerToken != nil { + in, out := &in.BearerToken, &out.BearerToken + *out = new(BearerTokenBitbucket) + (*in).DeepCopyInto(*out) + } + if in.CARef != nil { + in, out := &in.CARef, &out.CARef + *out = new(ConfigMapKeyRef) + **out = **in + } return } @@ -4054,6 +4203,11 @@ func (in *SCMProviderGeneratorGitlab) DeepCopyInto(out *SCMProviderGeneratorGitl *out = new(bool) **out = **in } + if in.CARef != nil { + in, out := &in.CARef, &out.CARef + *out = new(ConfigMapKeyRef) + **out = **in + } return } @@ -4099,6 +4253,72 @@ func (in *SignatureKey) DeepCopy() *SignatureKey { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceHydrator) DeepCopyInto(out *SourceHydrator) { + *out = *in + out.DrySource = in.DrySource + out.SyncSource = in.SyncSource + if in.HydrateTo != nil { + in, out := &in.HydrateTo, &out.HydrateTo + *out = new(HydrateTo) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceHydrator. +func (in *SourceHydrator) DeepCopy() *SourceHydrator { + if in == nil { + return nil + } + out := new(SourceHydrator) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SourceHydratorStatus) DeepCopyInto(out *SourceHydratorStatus) { + *out = *in + if in.LastSuccessfulOperation != nil { + in, out := &in.LastSuccessfulOperation, &out.LastSuccessfulOperation + *out = new(SuccessfulHydrateOperation) + (*in).DeepCopyInto(*out) + } + if in.CurrentOperation != nil { + in, out := &in.CurrentOperation, &out.CurrentOperation + *out = new(HydrateOperation) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceHydratorStatus. +func (in *SourceHydratorStatus) DeepCopy() *SourceHydratorStatus { + if in == nil { + return nil + } + out := new(SourceHydratorStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SuccessfulHydrateOperation) DeepCopyInto(out *SuccessfulHydrateOperation) { + *out = *in + in.SourceHydrator.DeepCopyInto(&out.SourceHydrator) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SuccessfulHydrateOperation. +func (in *SuccessfulHydrateOperation) DeepCopy() *SuccessfulHydrateOperation { + if in == nil { + return nil + } + out := new(SuccessfulHydrateOperation) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncOperation) DeepCopyInto(out *SyncOperation) { *out = *in @@ -4285,6 +4505,22 @@ func (in *SyncPolicyAutomated) DeepCopy() *SyncPolicyAutomated { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SyncSource) DeepCopyInto(out *SyncSource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyncSource. +func (in *SyncSource) DeepCopy() *SyncSource { + if in == nil { + return nil + } + out := new(SyncSource) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncStatus) DeepCopyInto(out *SyncStatus) { *out = *in diff --git a/pkg/client/clientset/versioned/doc.go b/pkg/client/clientset/versioned/doc.go deleted file mode 100644 index 0e0c2a8900e2c..0000000000000 --- a/pkg/client/clientset/versioned/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. -package versioned diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 5db236c542663..fe6096b4ca540 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -15,8 +15,12 @@ import ( // NewSimpleClientset returns a clientset that will respond with the provided objects. // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, -// without applying any validations and/or defaults. It shouldn't be considered a replacement +// without applying any field management, validations and/or defaults. It shouldn't be considered a replacement // for a real clientset and is mostly useful in simple unit tests. +// +// DEPRECATED: NewClientset replaces this with support for field management, which significantly improves +// server side apply testing. NewClientset is only available when apply configurations are generated (e.g. +// via --with-applyconfig). func NewSimpleClientset(objects ...runtime.Object) *Clientset { o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) for _, obj := range objects { diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go index b51e0cb94ea22..69546f4441eac 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/application.go @@ -4,14 +4,13 @@ package v1alpha1 import ( "context" - "time" v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" scheme "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" ) // ApplicationsGetter has a method to return a ApplicationInterface. @@ -35,128 +34,18 @@ type ApplicationInterface interface { // applications implements ApplicationInterface type applications struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList] } // newApplications returns a Applications func newApplications(c *ArgoprojV1alpha1Client, namespace string) *applications { return &applications{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.Application, *v1alpha1.ApplicationList]( + "applications", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.Application { return &v1alpha1.Application{} }, + func() *v1alpha1.ApplicationList { return &v1alpha1.ApplicationList{} }), } } - -// Get takes name of the application, and returns the corresponding application object, and an error if there is any. -func (c *applications) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applications"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of Applications that match those selectors. -func (c *applications) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ApplicationList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.ApplicationList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested applications. -func (c *applications) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any. -func (c *applications) Create(ctx context.Context, application *v1alpha1.Application, opts v1.CreateOptions) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Post(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(application). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any. -func (c *applications) Update(ctx context.Context, application *v1alpha1.Application, opts v1.UpdateOptions) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Put(). - Namespace(c.ns). - Resource("applications"). - Name(application.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(application). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the application and deletes it. Returns an error if one occurs. -func (c *applications) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("applications"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *applications) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("applications"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched application. -func (c *applications) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Application, err error) { - result = &v1alpha1.Application{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("applications"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go index 5c00011e7d1e6..9fadaabc0d910 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/applicationset.go @@ -4,14 +4,13 @@ package v1alpha1 import ( "context" - "time" v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" scheme "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" ) // ApplicationSetsGetter has a method to return a ApplicationSetInterface. @@ -35,128 +34,18 @@ type ApplicationSetInterface interface { // applicationSets implements ApplicationSetInterface type applicationSets struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList] } // newApplicationSets returns a ApplicationSets func newApplicationSets(c *ArgoprojV1alpha1Client, namespace string) *applicationSets { return &applicationSets{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.ApplicationSet, *v1alpha1.ApplicationSetList]( + "applicationsets", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.ApplicationSet { return &v1alpha1.ApplicationSet{} }, + func() *v1alpha1.ApplicationSetList { return &v1alpha1.ApplicationSetList{} }), } } - -// Get takes name of the applicationSet, and returns the corresponding applicationSet object, and an error if there is any. -func (c *applicationSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ApplicationSet, err error) { - result = &v1alpha1.ApplicationSet{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applicationsets"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of ApplicationSets that match those selectors. -func (c *applicationSets) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ApplicationSetList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.ApplicationSetList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("applicationsets"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested applicationSets. -func (c *applicationSets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("applicationsets"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a applicationSet and creates it. Returns the server's representation of the applicationSet, and an error, if there is any. -func (c *applicationSets) Create(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.CreateOptions) (result *v1alpha1.ApplicationSet, err error) { - result = &v1alpha1.ApplicationSet{} - err = c.client.Post(). - Namespace(c.ns). - Resource("applicationsets"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(applicationSet). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a applicationSet and updates it. Returns the server's representation of the applicationSet, and an error, if there is any. -func (c *applicationSets) Update(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.UpdateOptions) (result *v1alpha1.ApplicationSet, err error) { - result = &v1alpha1.ApplicationSet{} - err = c.client.Put(). - Namespace(c.ns). - Resource("applicationsets"). - Name(applicationSet.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(applicationSet). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the applicationSet and deletes it. Returns an error if one occurs. -func (c *applicationSets) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("applicationsets"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *applicationSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("applicationsets"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched applicationSet. -func (c *applicationSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ApplicationSet, err error) { - result = &v1alpha1.ApplicationSet{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("applicationsets"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go index 386f2db3f5822..a20ec8041dd55 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/appproject.go @@ -4,14 +4,13 @@ package v1alpha1 import ( "context" - "time" v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" scheme "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/scheme" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + gentype "k8s.io/client-go/gentype" ) // AppProjectsGetter has a method to return a AppProjectInterface. @@ -35,128 +34,18 @@ type AppProjectInterface interface { // appProjects implements AppProjectInterface type appProjects struct { - client rest.Interface - ns string + *gentype.ClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList] } // newAppProjects returns a AppProjects func newAppProjects(c *ArgoprojV1alpha1Client, namespace string) *appProjects { return &appProjects{ - client: c.RESTClient(), - ns: namespace, + gentype.NewClientWithList[*v1alpha1.AppProject, *v1alpha1.AppProjectList]( + "appprojects", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *v1alpha1.AppProject { return &v1alpha1.AppProject{} }, + func() *v1alpha1.AppProjectList { return &v1alpha1.AppProjectList{} }), } } - -// Get takes name of the appProject, and returns the corresponding appProject object, and an error if there is any. -func (c *appProjects) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of AppProjects that match those selectors. -func (c *appProjects) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AppProjectList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.AppProjectList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested appProjects. -func (c *appProjects) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a appProject and creates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *appProjects) Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Post(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(appProject). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a appProject and updates it. Returns the server's representation of the appProject, and an error, if there is any. -func (c *appProjects) Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Put(). - Namespace(c.ns). - Resource("appprojects"). - Name(appProject.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(appProject). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the appProject and deletes it. Returns an error if one occurs. -func (c *appProjects) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("appprojects"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *appProjects) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("appprojects"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched appProject. -func (c *appProjects) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AppProject, err error) { - result = &v1alpha1.AppProject{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("appprojects"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go index f70ce5423aa98..4a6cb8f9eaa30 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_application.go @@ -8,7 +8,6 @@ import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" @@ -20,28 +19,30 @@ type FakeApplications struct { ns string } -var applicationsResource = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "applications"} +var applicationsResource = v1alpha1.SchemeGroupVersion.WithResource("applications") -var applicationsKind = schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "Application"} +var applicationsKind = v1alpha1.SchemeGroupVersion.WithKind("Application") // Get takes name of the application, and returns the corresponding application object, and an error if there is any. func (c *FakeApplications) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Application, err error) { + emptyResult := &v1alpha1.Application{} obj, err := c.Fake. - Invokes(testing.NewGetAction(applicationsResource, c.ns, name), &v1alpha1.Application{}) + Invokes(testing.NewGetActionWithOptions(applicationsResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Application), err } // List takes label and field selectors, and returns the list of Applications that match those selectors. func (c *FakeApplications) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ApplicationList, err error) { + emptyResult := &v1alpha1.ApplicationList{} obj, err := c.Fake. - Invokes(testing.NewListAction(applicationsResource, applicationsKind, c.ns, opts), &v1alpha1.ApplicationList{}) + Invokes(testing.NewListActionWithOptions(applicationsResource, applicationsKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -60,28 +61,30 @@ func (c *FakeApplications) List(ctx context.Context, opts v1.ListOptions) (resul // Watch returns a watch.Interface that watches the requested applications. func (c *FakeApplications) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(applicationsResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(applicationsResource, c.ns, opts)) } // Create takes the representation of a application and creates it. Returns the server's representation of the application, and an error, if there is any. func (c *FakeApplications) Create(ctx context.Context, application *v1alpha1.Application, opts v1.CreateOptions) (result *v1alpha1.Application, err error) { + emptyResult := &v1alpha1.Application{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(applicationsResource, c.ns, application), &v1alpha1.Application{}) + Invokes(testing.NewCreateActionWithOptions(applicationsResource, c.ns, application, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Application), err } // Update takes the representation of a application and updates it. Returns the server's representation of the application, and an error, if there is any. func (c *FakeApplications) Update(ctx context.Context, application *v1alpha1.Application, opts v1.UpdateOptions) (result *v1alpha1.Application, err error) { + emptyResult := &v1alpha1.Application{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(applicationsResource, c.ns, application), &v1alpha1.Application{}) + Invokes(testing.NewUpdateActionWithOptions(applicationsResource, c.ns, application, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Application), err } @@ -96,7 +99,7 @@ func (c *FakeApplications) Delete(ctx context.Context, name string, opts v1.Dele // DeleteCollection deletes a collection of objects. func (c *FakeApplications) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(applicationsResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(applicationsResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.ApplicationList{}) return err @@ -104,11 +107,12 @@ func (c *FakeApplications) DeleteCollection(ctx context.Context, opts v1.DeleteO // Patch applies the patch and returns the patched application. func (c *FakeApplications) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Application, err error) { + emptyResult := &v1alpha1.Application{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(applicationsResource, c.ns, name, pt, data, subresources...), &v1alpha1.Application{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(applicationsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.Application), err } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_applicationset.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_applicationset.go index d1ae0997751b7..04157e3d04e72 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_applicationset.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_applicationset.go @@ -8,7 +8,6 @@ import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" @@ -20,28 +19,30 @@ type FakeApplicationSets struct { ns string } -var applicationsetsResource = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "applicationsets"} +var applicationsetsResource = v1alpha1.SchemeGroupVersion.WithResource("applicationsets") -var applicationsetsKind = schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "ApplicationSet"} +var applicationsetsKind = v1alpha1.SchemeGroupVersion.WithKind("ApplicationSet") // Get takes name of the applicationSet, and returns the corresponding applicationSet object, and an error if there is any. func (c *FakeApplicationSets) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ApplicationSet, err error) { + emptyResult := &v1alpha1.ApplicationSet{} obj, err := c.Fake. - Invokes(testing.NewGetAction(applicationsetsResource, c.ns, name), &v1alpha1.ApplicationSet{}) + Invokes(testing.NewGetActionWithOptions(applicationsetsResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.ApplicationSet), err } // List takes label and field selectors, and returns the list of ApplicationSets that match those selectors. func (c *FakeApplicationSets) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ApplicationSetList, err error) { + emptyResult := &v1alpha1.ApplicationSetList{} obj, err := c.Fake. - Invokes(testing.NewListAction(applicationsetsResource, applicationsetsKind, c.ns, opts), &v1alpha1.ApplicationSetList{}) + Invokes(testing.NewListActionWithOptions(applicationsetsResource, applicationsetsKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -60,28 +61,30 @@ func (c *FakeApplicationSets) List(ctx context.Context, opts v1.ListOptions) (re // Watch returns a watch.Interface that watches the requested applicationSets. func (c *FakeApplicationSets) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(applicationsetsResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(applicationsetsResource, c.ns, opts)) } // Create takes the representation of a applicationSet and creates it. Returns the server's representation of the applicationSet, and an error, if there is any. func (c *FakeApplicationSets) Create(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.CreateOptions) (result *v1alpha1.ApplicationSet, err error) { + emptyResult := &v1alpha1.ApplicationSet{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(applicationsetsResource, c.ns, applicationSet), &v1alpha1.ApplicationSet{}) + Invokes(testing.NewCreateActionWithOptions(applicationsetsResource, c.ns, applicationSet, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.ApplicationSet), err } // Update takes the representation of a applicationSet and updates it. Returns the server's representation of the applicationSet, and an error, if there is any. func (c *FakeApplicationSets) Update(ctx context.Context, applicationSet *v1alpha1.ApplicationSet, opts v1.UpdateOptions) (result *v1alpha1.ApplicationSet, err error) { + emptyResult := &v1alpha1.ApplicationSet{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(applicationsetsResource, c.ns, applicationSet), &v1alpha1.ApplicationSet{}) + Invokes(testing.NewUpdateActionWithOptions(applicationsetsResource, c.ns, applicationSet, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.ApplicationSet), err } @@ -96,7 +99,7 @@ func (c *FakeApplicationSets) Delete(ctx context.Context, name string, opts v1.D // DeleteCollection deletes a collection of objects. func (c *FakeApplicationSets) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(applicationsetsResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(applicationsetsResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.ApplicationSetList{}) return err @@ -104,11 +107,12 @@ func (c *FakeApplicationSets) DeleteCollection(ctx context.Context, opts v1.Dele // Patch applies the patch and returns the patched applicationSet. func (c *FakeApplicationSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ApplicationSet, err error) { + emptyResult := &v1alpha1.ApplicationSet{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(applicationsetsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ApplicationSet{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(applicationsetsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.ApplicationSet), err } diff --git a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go index 802699f4c70b6..d510e445a5d43 100644 --- a/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go +++ b/pkg/client/clientset/versioned/typed/application/v1alpha1/fake/fake_appproject.go @@ -8,7 +8,6 @@ import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" testing "k8s.io/client-go/testing" @@ -20,28 +19,30 @@ type FakeAppProjects struct { ns string } -var appprojectsResource = schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "appprojects"} +var appprojectsResource = v1alpha1.SchemeGroupVersion.WithResource("appprojects") -var appprojectsKind = schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "AppProject"} +var appprojectsKind = v1alpha1.SchemeGroupVersion.WithKind("AppProject") // Get takes name of the appProject, and returns the corresponding appProject object, and an error if there is any. func (c *FakeAppProjects) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AppProject, err error) { + emptyResult := &v1alpha1.AppProject{} obj, err := c.Fake. - Invokes(testing.NewGetAction(appprojectsResource, c.ns, name), &v1alpha1.AppProject{}) + Invokes(testing.NewGetActionWithOptions(appprojectsResource, c.ns, name, options), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AppProject), err } // List takes label and field selectors, and returns the list of AppProjects that match those selectors. func (c *FakeAppProjects) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AppProjectList, err error) { + emptyResult := &v1alpha1.AppProjectList{} obj, err := c.Fake. - Invokes(testing.NewListAction(appprojectsResource, appprojectsKind, c.ns, opts), &v1alpha1.AppProjectList{}) + Invokes(testing.NewListActionWithOptions(appprojectsResource, appprojectsKind, c.ns, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } label, _, _ := testing.ExtractFromListOptions(opts) @@ -60,28 +61,30 @@ func (c *FakeAppProjects) List(ctx context.Context, opts v1.ListOptions) (result // Watch returns a watch.Interface that watches the requested appProjects. func (c *FakeAppProjects) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(appprojectsResource, c.ns, opts)) + InvokesWatch(testing.NewWatchActionWithOptions(appprojectsResource, c.ns, opts)) } // Create takes the representation of a appProject and creates it. Returns the server's representation of the appProject, and an error, if there is any. func (c *FakeAppProjects) Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (result *v1alpha1.AppProject, err error) { + emptyResult := &v1alpha1.AppProject{} obj, err := c.Fake. - Invokes(testing.NewCreateAction(appprojectsResource, c.ns, appProject), &v1alpha1.AppProject{}) + Invokes(testing.NewCreateActionWithOptions(appprojectsResource, c.ns, appProject, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AppProject), err } // Update takes the representation of a appProject and updates it. Returns the server's representation of the appProject, and an error, if there is any. func (c *FakeAppProjects) Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (result *v1alpha1.AppProject, err error) { + emptyResult := &v1alpha1.AppProject{} obj, err := c.Fake. - Invokes(testing.NewUpdateAction(appprojectsResource, c.ns, appProject), &v1alpha1.AppProject{}) + Invokes(testing.NewUpdateActionWithOptions(appprojectsResource, c.ns, appProject, opts), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AppProject), err } @@ -96,7 +99,7 @@ func (c *FakeAppProjects) Delete(ctx context.Context, name string, opts v1.Delet // DeleteCollection deletes a collection of objects. func (c *FakeAppProjects) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(appprojectsResource, c.ns, listOpts) + action := testing.NewDeleteCollectionActionWithOptions(appprojectsResource, c.ns, opts, listOpts) _, err := c.Fake.Invokes(action, &v1alpha1.AppProjectList{}) return err @@ -104,11 +107,12 @@ func (c *FakeAppProjects) DeleteCollection(ctx context.Context, opts v1.DeleteOp // Patch applies the patch and returns the patched appProject. func (c *FakeAppProjects) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AppProject, err error) { + emptyResult := &v1alpha1.AppProject{} obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(appprojectsResource, c.ns, name, pt, data, subresources...), &v1alpha1.AppProject{}) + Invokes(testing.NewPatchSubresourceActionWithOptions(appprojectsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) if obj == nil { - return nil, err + return emptyResult, err } return obj.(*v1alpha1.AppProject), err } diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 7d04eeb35ed52..d2ace1f12022e 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -26,6 +26,7 @@ type sharedInformerFactory struct { lock sync.Mutex defaultResync time.Duration customResync map[reflect.Type]time.Duration + transform cache.TransformFunc informers map[reflect.Type]cache.SharedIndexInformer // startedInformers is used for tracking which informers have been started. @@ -64,6 +65,14 @@ func WithNamespace(namespace string) SharedInformerOption { } } +// WithTransform sets a transform on all informers. +func WithTransform(transform cache.TransformFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.transform = transform + return factory + } +} + // NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { return NewSharedInformerFactoryWithOptions(client, defaultResync) @@ -150,7 +159,7 @@ func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[ref return res } -// InternalInformerFor returns the SharedIndexInformer for obj using an internal +// InformerFor returns the SharedIndexInformer for obj using an internal // client. func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { f.lock.Lock() @@ -168,6 +177,7 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal } informer = newFunc(f.client, resyncPeriod) + informer.SetTransform(f.transform) f.informers[informerType] = informer return informer @@ -202,6 +212,7 @@ type SharedInformerFactory interface { // Start initializes all requested informers. They are handled in goroutines // which run until the stop channel gets closed. + // Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync. Start(stopCh <-chan struct{}) // Shutdown marks a factory as shutting down. At that point no new @@ -223,7 +234,7 @@ type SharedInformerFactory interface { // ForResource gives generic access to a shared informer of the matching type. ForResource(resource schema.GroupVersionResource) (GenericInformer, error) - // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // InformerFor returns the SharedIndexInformer for obj using an internal // client. InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer diff --git a/pkg/client/listers/application/v1alpha1/application.go b/pkg/client/listers/application/v1alpha1/application.go index 9b51b24284f3e..a58173cccff1b 100644 --- a/pkg/client/listers/application/v1alpha1/application.go +++ b/pkg/client/listers/application/v1alpha1/application.go @@ -4,8 +4,8 @@ package v1alpha1 import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" ) @@ -22,25 +22,17 @@ type ApplicationLister interface { // applicationLister implements the ApplicationLister interface. type applicationLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.Application] } // NewApplicationLister returns a new ApplicationLister. func NewApplicationLister(indexer cache.Indexer) ApplicationLister { - return &applicationLister{indexer: indexer} -} - -// List lists all Applications in the indexer. -func (s *applicationLister) List(selector labels.Selector) (ret []*v1alpha1.Application, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Application)) - }) - return ret, err + return &applicationLister{listers.New[*v1alpha1.Application](indexer, v1alpha1.Resource("application"))} } // Applications returns an object that can list and get Applications. func (s *applicationLister) Applications(namespace string) ApplicationNamespaceLister { - return applicationNamespaceLister{indexer: s.indexer, namespace: namespace} + return applicationNamespaceLister{listers.NewNamespaced[*v1alpha1.Application](s.ResourceIndexer, namespace)} } // ApplicationNamespaceLister helps list and get Applications. @@ -58,26 +50,5 @@ type ApplicationNamespaceLister interface { // applicationNamespaceLister implements the ApplicationNamespaceLister // interface. type applicationNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Applications in the indexer for a given namespace. -func (s applicationNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Application, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Application)) - }) - return ret, err -} - -// Get retrieves the Application from the indexer for a given namespace and name. -func (s applicationNamespaceLister) Get(name string) (*v1alpha1.Application, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("application"), name) - } - return obj.(*v1alpha1.Application), nil + listers.ResourceIndexer[*v1alpha1.Application] } diff --git a/pkg/client/listers/application/v1alpha1/applicationset.go b/pkg/client/listers/application/v1alpha1/applicationset.go index e56c4fedc5499..0f87e40e044b9 100644 --- a/pkg/client/listers/application/v1alpha1/applicationset.go +++ b/pkg/client/listers/application/v1alpha1/applicationset.go @@ -4,8 +4,8 @@ package v1alpha1 import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" ) @@ -22,25 +22,17 @@ type ApplicationSetLister interface { // applicationSetLister implements the ApplicationSetLister interface. type applicationSetLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.ApplicationSet] } // NewApplicationSetLister returns a new ApplicationSetLister. func NewApplicationSetLister(indexer cache.Indexer) ApplicationSetLister { - return &applicationSetLister{indexer: indexer} -} - -// List lists all ApplicationSets in the indexer. -func (s *applicationSetLister) List(selector labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ApplicationSet)) - }) - return ret, err + return &applicationSetLister{listers.New[*v1alpha1.ApplicationSet](indexer, v1alpha1.Resource("applicationset"))} } // ApplicationSets returns an object that can list and get ApplicationSets. func (s *applicationSetLister) ApplicationSets(namespace string) ApplicationSetNamespaceLister { - return applicationSetNamespaceLister{indexer: s.indexer, namespace: namespace} + return applicationSetNamespaceLister{listers.NewNamespaced[*v1alpha1.ApplicationSet](s.ResourceIndexer, namespace)} } // ApplicationSetNamespaceLister helps list and get ApplicationSets. @@ -58,26 +50,5 @@ type ApplicationSetNamespaceLister interface { // applicationSetNamespaceLister implements the ApplicationSetNamespaceLister // interface. type applicationSetNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all ApplicationSets in the indexer for a given namespace. -func (s applicationSetNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ApplicationSet, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ApplicationSet)) - }) - return ret, err -} - -// Get retrieves the ApplicationSet from the indexer for a given namespace and name. -func (s applicationSetNamespaceLister) Get(name string) (*v1alpha1.ApplicationSet, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("applicationset"), name) - } - return obj.(*v1alpha1.ApplicationSet), nil + listers.ResourceIndexer[*v1alpha1.ApplicationSet] } diff --git a/pkg/client/listers/application/v1alpha1/appproject.go b/pkg/client/listers/application/v1alpha1/appproject.go index f0813232c4cd7..21697453c9f9b 100644 --- a/pkg/client/listers/application/v1alpha1/appproject.go +++ b/pkg/client/listers/application/v1alpha1/appproject.go @@ -4,8 +4,8 @@ package v1alpha1 import ( v1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/listers" "k8s.io/client-go/tools/cache" ) @@ -22,25 +22,17 @@ type AppProjectLister interface { // appProjectLister implements the AppProjectLister interface. type appProjectLister struct { - indexer cache.Indexer + listers.ResourceIndexer[*v1alpha1.AppProject] } // NewAppProjectLister returns a new AppProjectLister. func NewAppProjectLister(indexer cache.Indexer) AppProjectLister { - return &appProjectLister{indexer: indexer} -} - -// List lists all AppProjects in the indexer. -func (s *appProjectLister) List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AppProject)) - }) - return ret, err + return &appProjectLister{listers.New[*v1alpha1.AppProject](indexer, v1alpha1.Resource("appproject"))} } // AppProjects returns an object that can list and get AppProjects. func (s *appProjectLister) AppProjects(namespace string) AppProjectNamespaceLister { - return appProjectNamespaceLister{indexer: s.indexer, namespace: namespace} + return appProjectNamespaceLister{listers.NewNamespaced[*v1alpha1.AppProject](s.ResourceIndexer, namespace)} } // AppProjectNamespaceLister helps list and get AppProjects. @@ -58,26 +50,5 @@ type AppProjectNamespaceLister interface { // appProjectNamespaceLister implements the AppProjectNamespaceLister // interface. type appProjectNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all AppProjects in the indexer for a given namespace. -func (s appProjectNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.AppProject, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.AppProject)) - }) - return ret, err -} - -// Get retrieves the AppProject from the indexer for a given namespace and name. -func (s appProjectNamespaceLister) Get(name string) (*v1alpha1.AppProject, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("appproject"), name) - } - return obj.(*v1alpha1.AppProject), nil + listers.ResourceIndexer[*v1alpha1.AppProject] } diff --git a/pkg/ratelimiter/ratelimiter.go b/pkg/ratelimiter/ratelimiter.go index 53536f7b39a62..b9f0f4a19fe6f 100644 --- a/pkg/ratelimiter/ratelimiter.go +++ b/pkg/ratelimiter/ratelimiter.go @@ -35,10 +35,10 @@ func GetDefaultAppRateLimiterConfig() *AppControllerRateLimiterConfig { // NewCustomAppControllerRateLimiter is a constructor for the rate limiter for a workqueue used by app controller. It has // both overall and per-item rate limiting. The overall is a token bucket and the per-item is exponential(with auto resets) -func NewCustomAppControllerRateLimiter(cfg *AppControllerRateLimiterConfig) workqueue.TypedRateLimiter[string] { - return workqueue.NewTypedMaxOfRateLimiter[string]( - NewItemExponentialRateLimiterWithAutoReset(cfg.BaseDelay, cfg.MaxDelay, cfg.FailureCoolDown, cfg.BackoffFactor), - &workqueue.TypedBucketRateLimiter[string]{Limiter: rate.NewLimiter(rate.Limit(cfg.BucketQPS), int(cfg.BucketSize))}, +func NewCustomAppControllerRateLimiter[T comparable](cfg *AppControllerRateLimiterConfig) workqueue.TypedRateLimiter[T] { + return workqueue.NewTypedMaxOfRateLimiter[T]( + NewItemExponentialRateLimiterWithAutoReset[T](cfg.BaseDelay, cfg.MaxDelay, cfg.FailureCoolDown, cfg.BackoffFactor), + &workqueue.TypedBucketRateLimiter[T]{Limiter: rate.NewLimiter(rate.Limit(cfg.BucketQPS), int(cfg.BucketSize))}, ) } @@ -49,7 +49,7 @@ type failureData struct { // ItemExponentialRateLimiterWithAutoReset does a simple baseDelay*2^ limit // dealing with max failures and expiration/resets are up dependent on the cooldown period -type ItemExponentialRateLimiterWithAutoReset struct { +type ItemExponentialRateLimiterWithAutoReset[T comparable] struct { failuresLock sync.Mutex failures map[interface{}]failureData @@ -59,10 +59,10 @@ type ItemExponentialRateLimiterWithAutoReset struct { backoffFactor float64 } -var _ workqueue.TypedRateLimiter[string] = &ItemExponentialRateLimiterWithAutoReset{} +var _ workqueue.TypedRateLimiter[string] = &ItemExponentialRateLimiterWithAutoReset[string]{} -func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.TypedRateLimiter[string] { - return &ItemExponentialRateLimiterWithAutoReset{ +func NewItemExponentialRateLimiterWithAutoReset[T comparable](baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.TypedRateLimiter[T] { + return &ItemExponentialRateLimiterWithAutoReset[T]{ failures: map[interface{}]failureData{}, baseDelay: baseDelay, maxDelay: maxDelay, @@ -71,7 +71,7 @@ func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCool } } -func (r *ItemExponentialRateLimiterWithAutoReset) When(item string) time.Duration { +func (r *ItemExponentialRateLimiterWithAutoReset[T]) When(item T) time.Duration { r.failuresLock.Lock() defer r.failuresLock.Unlock() @@ -109,14 +109,14 @@ func (r *ItemExponentialRateLimiterWithAutoReset) When(item string) time.Duratio return calculated } -func (r *ItemExponentialRateLimiterWithAutoReset) NumRequeues(item string) int { +func (r *ItemExponentialRateLimiterWithAutoReset[T]) NumRequeues(item T) int { r.failuresLock.Lock() defer r.failuresLock.Unlock() return r.failures[item].failures } -func (r *ItemExponentialRateLimiterWithAutoReset) Forget(item string) { +func (r *ItemExponentialRateLimiterWithAutoReset[T]) Forget(item T) { r.failuresLock.Lock() defer r.failuresLock.Unlock() diff --git a/renovate-presets/README.md b/renovate-presets/README.md new file mode 100644 index 0000000000000..ef15ce04b2c28 --- /dev/null +++ b/renovate-presets/README.md @@ -0,0 +1,60 @@ +# Renovate shared presets + +Presets makes rules easier to maintain and reusable across multiple repositories. + +# How to use a preset + +Reference the preset in the `extends` field of the `renovate.json` file in the repository. +Presets can reference other presets. (read more about [shared presets](https://docs.renovatebot.com/config-presets/)) + +```json +{ + "extends": [ + "github>argoproj/argo-cd//renovate-presets/custom-managers/bash.json5" +] +} +``` + +### Note : + +It would make sense to move this folder to a new repository in the future. + +Benefits: +- Avoids consuming the repository's CI/CD resources. +- Faster feedback loop for configuration changes. +- Avoid polluting the master git history. +- The `renovate.json` in each repository can be simplified to only include a single presets : + ```json + { + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>argoproj/renovate-presets//argoproj/argo-cd/renovate.json5" + ], + // rules are empty and this file won't need to be modified again. + "packageRules": [] + } + ``` +Inconvenient: +- Owners of a repository can impact the configuration of all repositories. Use codeowners to reduce the risk. + +Example of repo structure : +```shell +. +├── README.md +├── .github/CODEOWNERS +├── common.json5 # common presets for all repositories +├── fix/ +│ └── openssf-merge-confidence-columns.json5 +├── custom-managers/ +│ ├── bash.json5 +│ └── yaml.json5 +└── argoproj/ # organization + ├── argo-cd/ # repository + │ ├── devtools.json5 # rules specific to the devtool (CI and dev environment...) + │ ├── docs.json5 # rules specific to the docs folder. + │ ├── # etc... + │ └── renovate.json5 # this is the single preset referenced from the repository argopro/argo-cd. + └── argo-rollouts/ # repository + └── renovate.json5 + +``` diff --git a/renovate-presets/commons.json5 b/renovate-presets/commons.json5 new file mode 100644 index 0000000000000..f6676a1d28540 --- /dev/null +++ b/renovate-presets/commons.json5 @@ -0,0 +1,74 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "description": "Contains rules that makes sense to enforce by default.", + "dependencyDashboard": true, + "dependencyDashboardOSVVulnerabilitySummary": "all", + "osvVulnerabilityAlerts": true, + "vulnerabilityAlerts": { + "description": "Settings specific to PRs of type security", + "addLabels": ["security"] + }, + "extends": [ + "config:best-practices", + ":gitSignOff", + ":labels(dependencies)", + "customManagers:dockerfileVersions", + "security:openssf-scorecard", + "mergeConfidence:all-badges", + "github>argoproj/argo-cd//renovate-presets/fix/openssf-merge-confidence-columns.json5", + ], + "packageRules": [ + { + "description": "Define the label to make Renovate stop updating a PR.", + "stopUpdatingLabel": "renovate:stop-updating" + }, + { + "description": "Define the label to make Renovate rebase a PR.", + "rebaseLabel": "renovate:do-rebase" + }, + { + "description": "Define labels of the dependency dashboard issues.", + "dependencyDashboardLabels": [ + "dependencies", + ] + }, + { + "description": "Add label major to PRs with major updates", + "matchUpdateTypes": [ + "major" + ], + "addLabels": [ + "major" + ] + }, + { + "description": "Add labels for PRs related to javascript", + "matchDatasources": [ + "node-version", + "npm" + ], + "addLabels": [ + "javascript" + ] + }, + { + "description": "Add labels for PRs related to go", + "matchDatasources": [ + "golang-version", + "go" + ], + "addLabels": [ + "go" + ] + }, + { + "description": "Add labels for PRs related to python", + "matchCategories": [ + "python" + ], + "addLabels": [ + "python" + ] + } + ] +} \ No newline at end of file diff --git a/renovate-presets/custom-managers/shell.json5 b/renovate-presets/custom-managers/shell.json5 new file mode 100644 index 0000000000000..9ce3c1805d31e --- /dev/null +++ b/renovate-presets/custom-managers/shell.json5 @@ -0,0 +1,16 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "customManagers": [ + { + "description": "A generic custom manager for updating any shell scripts.", + "customType": "regex", + "fileMatch": [ + ".+\\.(?:bash|sh|ksh)$" + ], + "matchStrings": [ + "# renovate: datasource=(?.*?)(?: depName=(?.+?))? packageName=(?.+?)(?: versioning=(?.*?))?(?: extractVersion=(?.*?))?\\s.+?_VERSION\\s*=\\s*(?:'|\")(?[^(?:'|\")]+)(?:'|\")", + "# renovate: datasource=(?.*?)(?: depName=(?.+?))? packageName=(?.+?)(?: versioning=(?.*?))?(?: extractVersion=(?.*?))?\\s.+?_VERSION\\s*=\\s*(?[^'\"\\s]+)" + ] + } + ] +} \ No newline at end of file diff --git a/renovate-presets/custom-managers/yaml.json5 b/renovate-presets/custom-managers/yaml.json5 new file mode 100644 index 0000000000000..8729f611c8ea7 --- /dev/null +++ b/renovate-presets/custom-managers/yaml.json5 @@ -0,0 +1,16 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "customManagers": [ + { + "description": "A generic custom manager for updating any yaml fields ending by 'version:' (case insensitive)", + "customType": "regex", + "fileMatch": [ + ".github\\/workflows.+\\.(?:yml|yaml)$" + ], + "matchStrings": [ + "# renovate: datasource=(?.*?)(?: depName=(?.+?))? packageName=(?.+?)(?: versioning=(?.*?))?(?: extractVersion=(?.*?))?\\s.+?((?i)VERSION)\\s*:\\s*(?:'|\")(?[^(?:'|\")]+)(?:'|\")", + "# renovate: datasource=(?.*?)(?: depName=(?.+?))? packageName=(?.+?)(?: versioning=(?.*?))?(?: extractVersion=(?.*?))?\\s.+?((?i)VERSION)\\s*:\\s*(?[^'\"\\s]+)" + ] + } + ] +} \ No newline at end of file diff --git a/renovate-presets/devtool.json5 b/renovate-presets/devtool.json5 new file mode 100644 index 0000000000000..96ad51d3808e6 --- /dev/null +++ b/renovate-presets/devtool.json5 @@ -0,0 +1,72 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "description": "Rules specific to the devtool (CI, dev environment...)", + "packageRules": [ + { + "description": "Enable updates from specified datasources", + "matchDatasources": [ + "node-version", + "golang-version" + ], + "enabled": true + }, + { + "description": "Enable updates from specified go modules", + "matchDatasources": [ + "go" + ], + "matchPackageNames": [ + "github.com/golangci/golangci-lint" + ], + "enabled": true + }, + { + "description": "Enable updates from specified docker images", + "matchDatasources": [ + "docker" + ], + "matchPackageNames": [ + "docker.io/library/node", + "docker.io/library/golang" + ], + "enabled": true + }, + { + "description": "Group golang-version packages", + "groupName": "group golang", + "matchDatasources": [ + "docker", + "golang-version" + ], + "matchPackageNames": [ + "/(?:^|/)golang$/" + ] + }, + { + "description": "Group node-version packages", + "groupName": "group node", + "matchDatasources": [ + "docker", + "node-version" + ], + "matchPackageNames": [ + "/(?:^|/)node$/", + "!calico/node", + "!docker.io/calico/node", + "!kindest/node" + ] + }, + { + "description": "Example to reduce noise with the automerge features.", + "matchDatasources": [ + "golang-version" + ], + "matchUpdateTypes": [ + "patch", + "pin", + "digest" + ], + "automerge": false + } + ] +} \ No newline at end of file diff --git a/renovate-presets/docs.json5 b/renovate-presets/docs.json5 new file mode 100644 index 0000000000000..0eb67107f7308 --- /dev/null +++ b/renovate-presets/docs.json5 @@ -0,0 +1,21 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "description": "Rules specific to the docs directory", + "packageRules": [ + { + "description": "Group all dependencies from the docs directory", + "matchFileNames": ["docs/**"], + "matchCategories": [ + "python" + ], + "excludePackageNames": [ + "mkdocs-material" + ], + "groupName": "Docs dependencies", + "enabled": true + } + ] +} + + + diff --git a/renovate-presets/fix/disable-all-updates.json5 b/renovate-presets/fix/disable-all-updates.json5 new file mode 100644 index 0000000000000..5db24b27f02a9 --- /dev/null +++ b/renovate-presets/fix/disable-all-updates.json5 @@ -0,0 +1,13 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "description": "Disable all updates to avoid conflicts with dependabot, then enable what you need.", + "packageRules": [ + { + "matchPackageNames": [ + "*" + ], + "enabled": false + } + ] +} + diff --git a/renovate-presets/fix/openssf-merge-confidence-columns.json5 b/renovate-presets/fix/openssf-merge-confidence-columns.json5 new file mode 100644 index 0000000000000..b099487113bf5 --- /dev/null +++ b/renovate-presets/fix/openssf-merge-confidence-columns.json5 @@ -0,0 +1,22 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "description": "Merge the output of mergeConfidence:all-badges and security:openssf-scorecard. See https://github.com/renovatebot/renovate/discussions/25125 for rationale.", + "packageRules": [ + { + "matchPackagePatterns": [ + ".*" + ], + "prBodyColumns": [ + "Package", + "Type", + "Update", + "Change", + "Age", + "Adoption", + "Passing", + "Confidence", + "OpenSSF" + ] + } + ] +} \ No newline at end of file diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000000000..f395a491f4a76 --- /dev/null +++ b/renovate.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>argoproj/argo-cd//renovate-presets/commons.json5", + "github>argoproj/argo-cd//renovate-presets/custom-managers/shell.json5", + "github>argoproj/argo-cd//renovate-presets/custom-managers/yaml.json5", + "github>argoproj/argo-cd//renovate-presets/fix/disable-all-updates.json5", + "github>argoproj/argo-cd//renovate-presets/devtool.json5", + "github>argoproj/argo-cd//renovate-presets/docs.json5" + ] +} diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 0c3e12d811eb7..34adb3bc07fdc 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -59,7 +59,11 @@ type ManifestRequest struct { // This is used to surface "source not permitted" errors for Helm repositories ProjectSourceRepos []string `protobuf:"bytes,24,rep,name=projectSourceRepos,proto3" json:"projectSourceRepos,omitempty"` // This is used to surface "source not permitted" errors for Helm repositories - ProjectName string `protobuf:"bytes,25,opt,name=projectName,proto3" json:"projectName,omitempty"` + ProjectName string `protobuf:"bytes,25,opt,name=projectName,proto3" json:"projectName,omitempty"` + // argocd.argoproj.io/manifest-generate-paths annotation value of the Application to allow optimize which resources propagated to cmpserver + AnnotationManifestGeneratePaths string `protobuf:"bytes,26,opt,name=annotationManifestGeneratePaths,proto3" json:"annotationManifestGeneratePaths,omitempty"` + // Holds instance installation id + InstallationID string `protobuf:"bytes,27,opt,name=installationID,proto3" json:"installationID,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -252,6 +256,20 @@ func (m *ManifestRequest) GetProjectName() string { return "" } +func (m *ManifestRequest) GetAnnotationManifestGeneratePaths() string { + if m != nil { + return m.AnnotationManifestGeneratePaths + } + return "" +} + +func (m *ManifestRequest) GetInstallationID() string { + if m != nil { + return m.InstallationID + } + return "" +} + type ManifestRequestWithFiles struct { // Types that are valid to be assigned to Part: // *ManifestRequestWithFiles_Request @@ -2208,6 +2226,7 @@ type UpdateRevisionForPathsRequest struct { Revision string `protobuf:"bytes,12,opt,name=revision,proto3" json:"revision,omitempty"` Paths []string `protobuf:"bytes,13,rep,name=paths,proto3" json:"paths,omitempty"` NoRevisionCache bool `protobuf:"varint,14,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` + InstallationID string `protobuf:"bytes,15,opt,name=installationID,proto3" json:"installationID,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2344,7 +2363,17 @@ func (m *UpdateRevisionForPathsRequest) GetNoRevisionCache() bool { return false } +func (m *UpdateRevisionForPathsRequest) GetInstallationID() string { + if m != nil { + return m.InstallationID + } + return "" +} + type UpdateRevisionForPathsResponse struct { + // Changes indicates whether any changes were detected in the provided paths. If false, it means that the manifest + // cache was updated to the new revision. If true, it means that there are relevant changes in the repo files and + // that new manifests should be generated. Changes bool `protobuf:"varint,1,opt,name=changes,proto3" json:"changes,omitempty"` Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -2449,153 +2478,156 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2332 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0xcd, 0x73, 0x1c, 0x47, - 0x15, 0xd7, 0x7e, 0x6a, 0xf7, 0xad, 0x2c, 0xad, 0xda, 0xb6, 0x3c, 0xde, 0xd8, 0x2a, 0x65, 0xc0, - 0x2e, 0xc7, 0x4e, 0x76, 0xcb, 0x72, 0x25, 0x06, 0x27, 0x84, 0x52, 0x14, 0x5b, 0x72, 0x6c, 0xd9, - 0x62, 0xec, 0x84, 0x32, 0x18, 0xa8, 0xde, 0xd9, 0xde, 0xd9, 0xc9, 0xce, 0x47, 0x7b, 0xa6, 0x47, - 0x61, 0x5d, 0xc5, 0x09, 0x8a, 0x0b, 0x77, 0x0e, 0x5c, 0xf9, 0x1b, 0x28, 0x8e, 0x1c, 0x28, 0x0a, - 0x8e, 0x14, 0x17, 0xaa, 0xb8, 0x40, 0xf9, 0xc8, 0x5f, 0x41, 0x75, 0x4f, 0xcf, 0xe7, 0xce, 0xae, - 0x15, 0xd6, 0x56, 0x20, 0x17, 0x69, 0xfa, 0x75, 0xf7, 0x7b, 0xaf, 0x5f, 0xbf, 0xf7, 0xfa, 0xf7, - 0xba, 0x17, 0x2e, 0x7b, 0x84, 0xba, 0x3e, 0xf1, 0x8e, 0x88, 0xd7, 0x13, 0x9f, 0x26, 0x73, 0xbd, - 0x49, 0xea, 0xb3, 0x4b, 0x3d, 0x97, 0xb9, 0x08, 0x12, 0x4a, 0xe7, 0xbe, 0x61, 0xb2, 0x51, 0xd0, - 0xef, 0xea, 0xae, 0xdd, 0xc3, 0x9e, 0xe1, 0x52, 0xcf, 0xfd, 0x5c, 0x7c, 0xbc, 0xa3, 0x0f, 0x7a, - 0x47, 0xdb, 0x3d, 0x3a, 0x36, 0x7a, 0x98, 0x9a, 0x7e, 0x0f, 0x53, 0x6a, 0x99, 0x3a, 0x66, 0xa6, - 0xeb, 0xf4, 0x8e, 0xae, 0x63, 0x8b, 0x8e, 0xf0, 0xf5, 0x9e, 0x41, 0x1c, 0xe2, 0x61, 0x46, 0x06, - 0x21, 0xe7, 0xce, 0x1b, 0x86, 0xeb, 0x1a, 0x16, 0xe9, 0x89, 0x56, 0x3f, 0x18, 0xf6, 0x88, 0x4d, - 0x99, 0x14, 0xab, 0xfe, 0x7b, 0x05, 0xd6, 0x0e, 0xb0, 0x63, 0x0e, 0x89, 0xcf, 0x34, 0xf2, 0x2c, - 0x20, 0x3e, 0x43, 0x4f, 0xa1, 0xca, 0x95, 0x51, 0x4a, 0x5b, 0xa5, 0x2b, 0xad, 0xed, 0xfd, 0x6e, - 0xa2, 0x4d, 0x37, 0xd2, 0x46, 0x7c, 0xfc, 0x44, 0x1f, 0x74, 0x8f, 0xb6, 0xbb, 0x74, 0x6c, 0x74, - 0xb9, 0x36, 0xdd, 0x94, 0x36, 0xdd, 0x48, 0x9b, 0xae, 0x16, 0x2f, 0x4b, 0x13, 0x5c, 0x51, 0x07, - 0x1a, 0x1e, 0x39, 0x32, 0x7d, 0xd3, 0x75, 0x94, 0xf2, 0x56, 0xe9, 0x4a, 0x53, 0x8b, 0xdb, 0x48, - 0x81, 0x65, 0xc7, 0xdd, 0xc5, 0xfa, 0x88, 0x28, 0x95, 0xad, 0xd2, 0x95, 0x86, 0x16, 0x35, 0xd1, - 0x16, 0xb4, 0x30, 0xa5, 0xf7, 0x71, 0x9f, 0x58, 0xf7, 0xc8, 0x44, 0xa9, 0x8a, 0x89, 0x69, 0x12, - 0x9f, 0x8b, 0x29, 0x7d, 0x80, 0x6d, 0xa2, 0xd4, 0x44, 0x6f, 0xd4, 0x44, 0x17, 0xa0, 0xe9, 0x60, - 0x9b, 0xf8, 0x14, 0xeb, 0x44, 0x69, 0x88, 0xbe, 0x84, 0x80, 0x7e, 0x06, 0xeb, 0x29, 0xc5, 0x1f, - 0xb9, 0x81, 0xa7, 0x13, 0x05, 0xc4, 0xd2, 0x1f, 0x2e, 0xb6, 0xf4, 0x9d, 0x3c, 0x5b, 0x6d, 0x5a, - 0x12, 0xfa, 0x31, 0xd4, 0xc4, 0xce, 0x2b, 0xad, 0xad, 0xca, 0x2b, 0xb5, 0x76, 0xc8, 0x16, 0x39, - 0xb0, 0x4c, 0xad, 0xc0, 0x30, 0x1d, 0x5f, 0x59, 0x11, 0x12, 0x1e, 0x2f, 0x26, 0x61, 0xd7, 0x75, - 0x86, 0xa6, 0x71, 0x80, 0x1d, 0x6c, 0x10, 0x9b, 0x38, 0xec, 0x50, 0x30, 0xd7, 0x22, 0x21, 0xe8, - 0x39, 0xb4, 0xc7, 0x81, 0xcf, 0x5c, 0xdb, 0x7c, 0x4e, 0x1e, 0x52, 0x3e, 0xd7, 0x57, 0x4e, 0x09, - 0x6b, 0x3e, 0x58, 0x4c, 0xf0, 0xbd, 0x1c, 0x57, 0x6d, 0x4a, 0x0e, 0x77, 0x92, 0x71, 0xd0, 0x27, - 0x9f, 0x11, 0x4f, 0x78, 0xd7, 0x6a, 0xe8, 0x24, 0x29, 0x52, 0xe8, 0x46, 0xa6, 0x6c, 0xf9, 0xca, - 0xda, 0x56, 0x25, 0x74, 0xa3, 0x98, 0x84, 0xae, 0xc0, 0xda, 0x11, 0xf1, 0xcc, 0xe1, 0xe4, 0x91, - 0x69, 0x38, 0x98, 0x05, 0x1e, 0x51, 0xda, 0xc2, 0x15, 0xf3, 0x64, 0x64, 0xc3, 0xa9, 0x11, 0xb1, - 0x6c, 0x6e, 0xf2, 0x5d, 0x8f, 0x0c, 0x7c, 0x65, 0x5d, 0xd8, 0x77, 0x6f, 0xf1, 0x1d, 0x14, 0xec, - 0xb4, 0x2c, 0x77, 0xae, 0x98, 0xe3, 0x6a, 0x32, 0x52, 0xc2, 0x18, 0x41, 0xa1, 0x62, 0x39, 0x32, - 0xba, 0x0c, 0xab, 0xcc, 0xc3, 0xfa, 0xd8, 0x74, 0x8c, 0x03, 0xc2, 0x46, 0xee, 0x40, 0x39, 0x2d, - 0x2c, 0x91, 0xa3, 0x22, 0x1d, 0x10, 0x71, 0x70, 0xdf, 0x22, 0x83, 0xd0, 0x17, 0x1f, 0x4f, 0x28, - 0xf1, 0x95, 0x33, 0x62, 0x15, 0x37, 0xba, 0xa9, 0x0c, 0x95, 0x4b, 0x10, 0xdd, 0xdb, 0x53, 0xb3, - 0x6e, 0x3b, 0xcc, 0x9b, 0x68, 0x05, 0xec, 0xd0, 0x18, 0x5a, 0x7c, 0x1d, 0x91, 0x2b, 0x9c, 0x15, - 0xae, 0x70, 0x77, 0x31, 0x1b, 0xed, 0x27, 0x0c, 0xb5, 0x34, 0x77, 0xd4, 0x05, 0x34, 0xc2, 0xfe, - 0x41, 0x60, 0x31, 0x93, 0x5a, 0x24, 0x54, 0xc3, 0x57, 0x36, 0x84, 0x99, 0x0a, 0x7a, 0xd0, 0x3d, - 0x00, 0x8f, 0x0c, 0xa3, 0x71, 0xe7, 0xc4, 0xca, 0xaf, 0xcd, 0x5b, 0xb9, 0x16, 0x8f, 0x0e, 0x57, - 0x9c, 0x9a, 0xce, 0x85, 0xf3, 0x65, 0x10, 0x9d, 0xc9, 0x68, 0x17, 0x61, 0xad, 0x08, 0x17, 0x2b, - 0xe8, 0xe1, 0xbe, 0x28, 0xa9, 0x22, 0x69, 0x9d, 0x0f, 0xbd, 0x35, 0x45, 0xea, 0xdc, 0x86, 0x73, - 0x33, 0x4c, 0x8d, 0xda, 0x50, 0x19, 0x93, 0x89, 0x48, 0xd1, 0x4d, 0x8d, 0x7f, 0xa2, 0x33, 0x50, - 0x3b, 0xc2, 0x56, 0x40, 0x44, 0x52, 0x6d, 0x68, 0x61, 0xe3, 0x56, 0xf9, 0x5b, 0xa5, 0xce, 0x2f, - 0x4b, 0xb0, 0x96, 0x53, 0xbc, 0x60, 0xfe, 0x8f, 0xd2, 0xf3, 0x5f, 0x81, 0x1b, 0x0f, 0x1f, 0x63, - 0xcf, 0x20, 0x2c, 0xa5, 0x88, 0xfa, 0xb7, 0x12, 0x28, 0x39, 0x8b, 0x7e, 0xdf, 0x64, 0xa3, 0x3b, - 0xa6, 0x45, 0x7c, 0x74, 0x13, 0x96, 0xbd, 0x90, 0x26, 0x0f, 0x9e, 0x37, 0xe6, 0x6c, 0xc4, 0xfe, - 0x92, 0x16, 0x8d, 0x46, 0x1f, 0x42, 0xc3, 0x26, 0x0c, 0x0f, 0x30, 0xc3, 0x52, 0xf7, 0xad, 0xa2, - 0x99, 0x5c, 0xca, 0x81, 0x1c, 0xb7, 0xbf, 0xa4, 0xc5, 0x73, 0xd0, 0xbb, 0x50, 0xd3, 0x47, 0x81, - 0x33, 0x16, 0x47, 0x4e, 0x6b, 0xfb, 0xe2, 0xac, 0xc9, 0xbb, 0x7c, 0xd0, 0xfe, 0x92, 0x16, 0x8e, - 0xfe, 0xa8, 0x0e, 0x55, 0x8a, 0x3d, 0xa6, 0xde, 0x81, 0x33, 0x45, 0x22, 0xf8, 0x39, 0xa7, 0x8f, - 0x88, 0x3e, 0xf6, 0x03, 0x5b, 0x9a, 0x39, 0x6e, 0x23, 0x04, 0x55, 0xdf, 0x7c, 0x1e, 0x9a, 0xba, - 0xa2, 0x89, 0x6f, 0xf5, 0x2d, 0x58, 0x9f, 0x92, 0xc6, 0x37, 0x35, 0xd4, 0x8d, 0x73, 0x58, 0x91, - 0xa2, 0xd5, 0x00, 0xce, 0x3e, 0x16, 0xb6, 0x88, 0x93, 0xfd, 0x49, 0x9c, 0xdc, 0xea, 0x3e, 0x6c, - 0xe4, 0xc5, 0xfa, 0xd4, 0x75, 0x7c, 0xc2, 0x5d, 0x5f, 0x64, 0x47, 0x93, 0x0c, 0x92, 0x5e, 0xa1, - 0x45, 0x43, 0x2b, 0xe8, 0x51, 0x7f, 0x5b, 0x86, 0x0d, 0x8d, 0xf8, 0xae, 0x75, 0x44, 0xa2, 0xd4, - 0x75, 0x32, 0xe0, 0xe3, 0x87, 0x50, 0xc1, 0x94, 0x4a, 0x37, 0xb9, 0xfb, 0xca, 0x8e, 0x77, 0x8d, - 0x73, 0x45, 0x6f, 0xc3, 0x3a, 0xb6, 0xfb, 0xa6, 0x11, 0xb8, 0x81, 0x1f, 0x2d, 0x4b, 0x38, 0x55, - 0x53, 0x9b, 0xee, 0xe0, 0xe1, 0xef, 0x8b, 0x88, 0xbc, 0xeb, 0x0c, 0xc8, 0x4f, 0x05, 0xa2, 0xa9, - 0x68, 0x69, 0x92, 0xaa, 0xc3, 0xb9, 0x29, 0x23, 0x49, 0x83, 0xa7, 0x41, 0x54, 0x29, 0x07, 0xa2, - 0x0a, 0xd5, 0x28, 0xcf, 0x50, 0x43, 0x7d, 0x51, 0x82, 0x76, 0x12, 0x5c, 0x92, 0xfd, 0x05, 0x68, - 0xda, 0x92, 0xe6, 0x2b, 0x25, 0x91, 0xc1, 0x12, 0x42, 0x16, 0x4f, 0x95, 0xf3, 0x78, 0x6a, 0x03, - 0xea, 0x21, 0xdc, 0x95, 0x4b, 0x97, 0xad, 0x8c, 0xca, 0xd5, 0x9c, 0xca, 0x9b, 0x00, 0x7e, 0x9c, - 0xe1, 0x94, 0xba, 0xe8, 0x4d, 0x51, 0x90, 0x0a, 0x2b, 0xe1, 0xe9, 0xab, 0x11, 0x3f, 0xb0, 0x98, - 0xb2, 0x2c, 0x46, 0x64, 0x68, 0x22, 0xde, 0x5c, 0xdb, 0xc6, 0xce, 0xc0, 0x57, 0x1a, 0x42, 0xe5, - 0xb8, 0xad, 0xba, 0xb0, 0x76, 0xdf, 0xe4, 0xeb, 0x1b, 0xfa, 0x27, 0x13, 0x2a, 0xef, 0x41, 0x95, - 0x0b, 0xe3, 0x4a, 0xf5, 0x3d, 0xec, 0xe8, 0x23, 0x12, 0xd9, 0x31, 0x6e, 0xf3, 0x24, 0xc0, 0xb0, - 0xe1, 0x2b, 0x65, 0x41, 0x17, 0xdf, 0xea, 0xef, 0xcb, 0xa1, 0xa6, 0x3b, 0x94, 0xfa, 0x5f, 0x3d, - 0x1c, 0x2f, 0x06, 0x08, 0x95, 0x69, 0x80, 0x90, 0x53, 0xf9, 0xcb, 0x00, 0x84, 0x57, 0x74, 0xc8, - 0xa9, 0x01, 0x2c, 0xef, 0x50, 0xca, 0x15, 0x41, 0xd7, 0xa1, 0x8a, 0x29, 0x0d, 0x0d, 0x9e, 0xcb, - 0xe7, 0x72, 0x08, 0xff, 0x2f, 0x55, 0x12, 0x43, 0x3b, 0x37, 0xa1, 0x19, 0x93, 0x5e, 0x26, 0xb6, - 0x99, 0x16, 0xbb, 0x05, 0x10, 0x22, 0xe0, 0xbb, 0xce, 0xd0, 0xe5, 0x5b, 0xca, 0x03, 0x41, 0x4e, - 0x15, 0xdf, 0xea, 0xad, 0x68, 0x84, 0xd0, 0xed, 0x6d, 0xa8, 0x99, 0x8c, 0xd8, 0x91, 0x72, 0x1b, - 0x69, 0xe5, 0x12, 0x46, 0x5a, 0x38, 0x48, 0xfd, 0x73, 0x03, 0xce, 0xf3, 0x1d, 0x7b, 0x24, 0x42, - 0x68, 0x87, 0xd2, 0x8f, 0x09, 0xc3, 0xa6, 0xe5, 0x7f, 0x2f, 0x20, 0xde, 0xe4, 0x35, 0x3b, 0x86, - 0x01, 0xf5, 0x30, 0x02, 0x65, 0xb6, 0x7c, 0xe5, 0xc5, 0x90, 0x64, 0x9f, 0x54, 0x40, 0x95, 0xd7, - 0x53, 0x01, 0x15, 0x55, 0x24, 0xd5, 0x13, 0xaa, 0x48, 0x66, 0x17, 0xa5, 0xa9, 0x52, 0xb7, 0x9e, - 0x2d, 0x75, 0x0b, 0x80, 0xfe, 0xf2, 0x71, 0x81, 0x7e, 0xa3, 0x10, 0xe8, 0xdb, 0x85, 0x71, 0xdc, - 0x14, 0xe6, 0xfe, 0x4e, 0xda, 0x03, 0x67, 0xfa, 0xda, 0x22, 0x90, 0x1f, 0x5e, 0x2b, 0xe4, 0xff, - 0x34, 0x03, 0xe1, 0xc3, 0x22, 0xfa, 0xdd, 0xe3, 0xad, 0x69, 0x0e, 0x98, 0xff, 0xda, 0x41, 0xef, - 0x5f, 0x08, 0xc4, 0x45, 0xdd, 0xc4, 0x06, 0xf1, 0x61, 0xcf, 0xcf, 0x21, 0x7e, 0xec, 0xca, 0xa4, - 0xc5, 0xbf, 0xd1, 0x35, 0xa8, 0x72, 0x23, 0x4b, 0x48, 0x7c, 0x2e, 0x6d, 0x4f, 0xbe, 0x13, 0x3b, - 0x94, 0x3e, 0xa2, 0x44, 0xd7, 0xc4, 0x20, 0x74, 0x0b, 0x9a, 0xb1, 0xe3, 0xcb, 0xc8, 0xba, 0x90, - 0x9e, 0x11, 0xc7, 0x49, 0x34, 0x2d, 0x19, 0xce, 0xe7, 0x0e, 0x4c, 0x8f, 0xe8, 0x02, 0x30, 0xd6, - 0xa6, 0xe7, 0x7e, 0x1c, 0x75, 0xc6, 0x73, 0xe3, 0xe1, 0xe8, 0x3a, 0xd4, 0xc3, 0x5b, 0x07, 0x11, - 0x41, 0xad, 0xed, 0xf3, 0xd3, 0xc9, 0x34, 0x9a, 0x25, 0x07, 0xaa, 0x7f, 0x2a, 0xc1, 0x9b, 0x89, - 0x43, 0x44, 0xd1, 0x14, 0x61, 0xf6, 0xaf, 0xfe, 0xc4, 0xbd, 0x0c, 0xab, 0xa2, 0x48, 0x48, 0x2e, - 0x1f, 0xc2, 0x7b, 0xb0, 0x1c, 0x55, 0xfd, 0x5d, 0x09, 0x2e, 0x4d, 0xaf, 0x63, 0x77, 0x84, 0x3d, - 0x16, 0x6f, 0xef, 0x49, 0xac, 0x25, 0x3a, 0xf0, 0xca, 0xc9, 0x81, 0x97, 0x59, 0x5f, 0x25, 0xbb, - 0x3e, 0xf5, 0x0f, 0x65, 0x68, 0xa5, 0x1c, 0xa8, 0xe8, 0xc0, 0xe4, 0x60, 0x50, 0xf8, 0xad, 0x28, - 0x0b, 0xc5, 0xa1, 0xd0, 0xd4, 0x52, 0x14, 0x34, 0x06, 0xa0, 0xd8, 0xc3, 0x36, 0x61, 0xc4, 0xe3, - 0x99, 0x9c, 0x47, 0xfc, 0xbd, 0xc5, 0xb3, 0xcb, 0x61, 0xc4, 0x53, 0x4b, 0xb1, 0xe7, 0x68, 0x56, - 0x88, 0xf6, 0x65, 0xfe, 0x96, 0x2d, 0xf4, 0x05, 0xac, 0x0e, 0x4d, 0x8b, 0x1c, 0x26, 0x8a, 0xd4, - 0x85, 0x22, 0x0f, 0x17, 0x57, 0xe4, 0x4e, 0x9a, 0xaf, 0x96, 0x13, 0xa3, 0x5e, 0x85, 0x76, 0x3e, - 0x9e, 0xb8, 0x92, 0xa6, 0x8d, 0x8d, 0xd8, 0x5a, 0xb2, 0xa5, 0x22, 0x68, 0xe7, 0xe3, 0x47, 0xfd, - 0x67, 0x19, 0xce, 0xc6, 0xec, 0x76, 0x1c, 0xc7, 0x0d, 0x1c, 0x5d, 0x5c, 0xe4, 0x15, 0xee, 0xc5, - 0x19, 0xa8, 0x31, 0x93, 0x59, 0x31, 0xf0, 0x11, 0x0d, 0x7e, 0x76, 0x31, 0xd7, 0xb5, 0x98, 0x49, - 0xe5, 0x06, 0x47, 0xcd, 0x70, 0xef, 0x9f, 0x05, 0xa6, 0x47, 0x06, 0x22, 0x13, 0x34, 0xb4, 0xb8, - 0xcd, 0xfb, 0x38, 0xaa, 0x11, 0x10, 0x3f, 0x34, 0x66, 0xdc, 0x16, 0x7e, 0xef, 0x5a, 0x16, 0xd1, - 0xb9, 0x39, 0x52, 0x45, 0x40, 0x8e, 0x2a, 0x8a, 0x0b, 0xe6, 0x99, 0x8e, 0x21, 0x4b, 0x00, 0xd9, - 0xe2, 0x7a, 0x62, 0xcf, 0xc3, 0x13, 0x89, 0xfc, 0xc3, 0x06, 0xfa, 0x00, 0x2a, 0x36, 0xa6, 0xf2, - 0xa0, 0xbb, 0x9a, 0xc9, 0x0e, 0x45, 0x16, 0xe8, 0x1e, 0x60, 0x1a, 0x9e, 0x04, 0x7c, 0x5a, 0xe7, - 0x3d, 0x68, 0x44, 0x84, 0x2f, 0x05, 0x09, 0x3f, 0x87, 0x53, 0x99, 0xe4, 0x83, 0x9e, 0xc0, 0x46, - 0xe2, 0x51, 0x69, 0x81, 0x12, 0x04, 0xbe, 0xf9, 0x52, 0xcd, 0xb4, 0x19, 0x0c, 0xd4, 0x67, 0xb0, - 0xce, 0x5d, 0x46, 0x04, 0xfe, 0x09, 0x95, 0x36, 0xef, 0x43, 0x33, 0x16, 0x59, 0xe8, 0x33, 0x1d, - 0x68, 0x1c, 0x45, 0x17, 0xac, 0x61, 0x6d, 0x13, 0xb7, 0xd5, 0x1d, 0x40, 0x69, 0x7d, 0xe5, 0x09, - 0x74, 0x2d, 0x0b, 0x8a, 0xcf, 0xe6, 0x8f, 0x1b, 0x31, 0x3c, 0xc2, 0xc4, 0x7f, 0x2f, 0xc3, 0xda, - 0x9e, 0x29, 0xee, 0x48, 0x4e, 0x28, 0xc9, 0x5d, 0x85, 0xb6, 0x1f, 0xf4, 0x6d, 0x77, 0x10, 0x58, - 0x44, 0x82, 0x02, 0x79, 0xd2, 0x4f, 0xd1, 0xe7, 0x25, 0x3f, 0x6e, 0x2c, 0x8a, 0xd9, 0x48, 0x56, - 0xbf, 0xe2, 0x1b, 0x7d, 0x00, 0xe7, 0x1f, 0x90, 0x2f, 0xe4, 0x7a, 0xf6, 0x2c, 0xb7, 0xdf, 0x37, - 0x1d, 0x23, 0x12, 0x52, 0x13, 0x42, 0x66, 0x0f, 0x28, 0x82, 0x8a, 0xf5, 0x62, 0xa8, 0x18, 0x57, - 0xd0, 0xbb, 0xae, 0x6d, 0x9b, 0x4c, 0x22, 0xca, 0x0c, 0x4d, 0xfd, 0x79, 0x09, 0xda, 0x89, 0x65, - 0xe5, 0xde, 0xdc, 0x0c, 0x63, 0x28, 0xdc, 0x99, 0x4b, 0xe9, 0x9d, 0xc9, 0x0f, 0xfd, 0xef, 0xc3, - 0x67, 0x25, 0x1d, 0x3e, 0xbf, 0x2a, 0xc3, 0xd9, 0x3d, 0x93, 0x45, 0x89, 0xcb, 0xfc, 0x7f, 0xdb, - 0xe5, 0x82, 0x3d, 0xa9, 0x1e, 0x6f, 0x4f, 0x6a, 0x05, 0x7b, 0xd2, 0x85, 0x8d, 0xbc, 0x31, 0xe4, - 0xc6, 0x9c, 0x81, 0x1a, 0xf7, 0xa0, 0xe8, 0x5e, 0x21, 0x6c, 0xa8, 0xff, 0xa8, 0xc3, 0xc5, 0x4f, - 0xe9, 0x00, 0xb3, 0xf8, 0xce, 0xe8, 0x8e, 0xeb, 0x1d, 0xf2, 0xae, 0x93, 0xb1, 0x62, 0xee, 0x9d, - 0xae, 0x3c, 0xf7, 0x9d, 0xae, 0x32, 0xe7, 0x9d, 0xae, 0x7a, 0xac, 0x77, 0xba, 0xda, 0x89, 0xbd, - 0xd3, 0x4d, 0xd7, 0x5a, 0xf5, 0xc2, 0x5a, 0xeb, 0x49, 0xa6, 0x1e, 0x59, 0x16, 0x61, 0xf3, 0xed, - 0x74, 0xd8, 0xcc, 0xdd, 0x9d, 0xb9, 0x0f, 0x0c, 0xb9, 0xe7, 0xad, 0xc6, 0x4b, 0x9f, 0xb7, 0x9a, - 0xd3, 0xcf, 0x5b, 0xc5, 0x2f, 0x24, 0x30, 0xf3, 0x85, 0xe4, 0x32, 0xac, 0xfa, 0x13, 0x47, 0x27, - 0x83, 0xf8, 0x26, 0xb1, 0x15, 0x2e, 0x3b, 0x4b, 0xcd, 0x44, 0xc4, 0x4a, 0x2e, 0x22, 0x62, 0x4f, - 0x3d, 0x95, 0xf2, 0xd4, 0xa2, 0x38, 0x59, 0x2d, 0x8c, 0x93, 0xff, 0x9d, 0x22, 0xea, 0x33, 0xd8, - 0x9c, 0xb5, 0x7b, 0x32, 0x28, 0x15, 0x58, 0xd6, 0x47, 0xd8, 0x31, 0xc4, 0x75, 0x9f, 0xa8, 0xea, - 0x65, 0x73, 0x1e, 0xea, 0xdf, 0xfe, 0x23, 0xc0, 0x7a, 0x82, 0xe6, 0xf9, 0x5f, 0x53, 0x27, 0xe8, - 0x21, 0xb4, 0xf7, 0xe4, 0x53, 0x7e, 0x74, 0x41, 0x8b, 0xe6, 0xbd, 0x89, 0x74, 0x2e, 0x14, 0x77, - 0x86, 0xaa, 0xa9, 0x4b, 0x48, 0x87, 0xf3, 0x79, 0x86, 0xc9, 0xf3, 0xcb, 0x37, 0xe7, 0x70, 0x8e, - 0x47, 0xbd, 0x4c, 0xc4, 0x95, 0x12, 0x7a, 0x02, 0xab, 0xd9, 0x47, 0x02, 0x94, 0x81, 0x37, 0x85, - 0xef, 0x16, 0x1d, 0x75, 0xde, 0x90, 0x58, 0xff, 0xa7, 0xdc, 0x0d, 0x32, 0xf7, 0xe1, 0x48, 0xcd, - 0x56, 0xfa, 0x45, 0x2f, 0x0a, 0x9d, 0x6f, 0xcc, 0x1d, 0x13, 0x73, 0x7f, 0x1f, 0x1a, 0xd1, 0x1d, - 0x71, 0xd6, 0xcc, 0xb9, 0x9b, 0xe3, 0x4e, 0x3b, 0xcb, 0x6f, 0xe8, 0xab, 0x4b, 0xe8, 0xc3, 0x70, - 0xf2, 0x0e, 0xa5, 0x05, 0x93, 0x53, 0x37, 0xa3, 0x9d, 0xd3, 0x05, 0xb7, 0x91, 0xea, 0x12, 0xfa, - 0x2e, 0xb4, 0xf8, 0xd7, 0xa1, 0x7c, 0x44, 0xdf, 0xe8, 0x86, 0xbf, 0xd9, 0xe8, 0x46, 0xbf, 0xd9, - 0xe8, 0xde, 0xb6, 0x29, 0x9b, 0x74, 0x0a, 0xae, 0x0b, 0x25, 0x83, 0xa7, 0x70, 0x6a, 0x8f, 0xb0, - 0xa4, 0xba, 0x47, 0x97, 0x8e, 0x75, 0x07, 0xd2, 0x51, 0xf3, 0xc3, 0xa6, 0x2f, 0x08, 0xd4, 0x25, - 0xf4, 0xeb, 0x12, 0x9c, 0xde, 0x23, 0x2c, 0x5f, 0x2f, 0xa3, 0x77, 0x8a, 0x85, 0xcc, 0xa8, 0xab, - 0x3b, 0x0f, 0x16, 0x8d, 0xc9, 0x2c, 0x5b, 0x75, 0x09, 0xfd, 0xa6, 0x04, 0xe7, 0x52, 0x8a, 0xa5, - 0x0b, 0x60, 0x74, 0x7d, 0xbe, 0x72, 0x05, 0xc5, 0x72, 0xe7, 0x93, 0x05, 0x7f, 0x1b, 0x91, 0x62, - 0xa9, 0x2e, 0xa1, 0x43, 0xb1, 0x27, 0x09, 0xde, 0x45, 0x17, 0x0b, 0x81, 0x6d, 0x2c, 0x7d, 0x73, - 0x56, 0x77, 0xbc, 0x0f, 0x9f, 0x40, 0x6b, 0x8f, 0xb0, 0x08, 0x78, 0x65, 0x3d, 0x2d, 0x87, 0x89, - 0xb3, 0xa1, 0x9a, 0xc7, 0x6a, 0xc2, 0x63, 0xd6, 0x43, 0x5e, 0x29, 0x70, 0x91, 0x8d, 0xd5, 0x42, - 0x14, 0x96, 0xf5, 0x98, 0x62, 0x6c, 0xa2, 0x2e, 0xa1, 0x67, 0xb0, 0x51, 0x9c, 0x2a, 0xd1, 0x5b, - 0xc7, 0x3e, 0x0c, 0x3b, 0x57, 0x8f, 0x33, 0x34, 0x12, 0xf9, 0xd1, 0xce, 0x5f, 0x5e, 0x6c, 0x96, - 0xfe, 0xfa, 0x62, 0xb3, 0xf4, 0xaf, 0x17, 0x9b, 0xa5, 0x1f, 0xdc, 0x78, 0xc9, 0x6f, 0xa8, 0x52, - 0x3f, 0xcb, 0xc2, 0xd4, 0xd4, 0x2d, 0x93, 0x38, 0xac, 0x5f, 0x17, 0xf1, 0x76, 0xe3, 0x3f, 0x01, - 0x00, 0x00, 0xff, 0xff, 0xe6, 0x4d, 0x67, 0x16, 0xb5, 0x25, 0x00, 0x00, + // 2376 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x1a, 0x4d, 0x73, 0x1c, 0x47, + 0x55, 0xfb, 0x25, 0xed, 0x3e, 0x59, 0x5f, 0x6d, 0x5b, 0x1e, 0xaf, 0x6d, 0xa1, 0x0c, 0xd8, 0xe5, + 0xd8, 0xc9, 0xaa, 0x2c, 0x57, 0x62, 0x70, 0x42, 0x28, 0x45, 0xb6, 0x25, 0xc7, 0x96, 0x2d, 0xc6, + 0x4e, 0x28, 0x83, 0x81, 0xea, 0x9d, 0x6d, 0xed, 0x76, 0x34, 0x1f, 0xed, 0x99, 0x1e, 0x05, 0xb9, + 0x8a, 0x0b, 0x50, 0x5c, 0xb8, 0x73, 0xe0, 0xca, 0x6f, 0xa0, 0x38, 0x72, 0xa0, 0x28, 0x38, 0x52, + 0x5c, 0xb8, 0x50, 0x05, 0xe5, 0x5f, 0x42, 0xf5, 0xc7, 0x7c, 0xee, 0xec, 0x4a, 0x61, 0x6d, 0x05, + 0xb8, 0x48, 0xd3, 0xaf, 0x5f, 0xbf, 0xf7, 0xfa, 0x7d, 0xf5, 0x7b, 0xdd, 0x0b, 0x57, 0x02, 0xc2, + 0xfc, 0x90, 0x04, 0x07, 0x24, 0x58, 0x93, 0x9f, 0x94, 0xfb, 0xc1, 0x61, 0xe6, 0xb3, 0xc3, 0x02, + 0x9f, 0xfb, 0x08, 0x52, 0x48, 0xfb, 0x61, 0x9f, 0xf2, 0x41, 0xd4, 0xed, 0xd8, 0xbe, 0xbb, 0x86, + 0x83, 0xbe, 0xcf, 0x02, 0xff, 0x73, 0xf9, 0xf1, 0xae, 0xdd, 0x5b, 0x3b, 0x58, 0x5f, 0x63, 0xfb, + 0xfd, 0x35, 0xcc, 0x68, 0xb8, 0x86, 0x19, 0x73, 0xa8, 0x8d, 0x39, 0xf5, 0xbd, 0xb5, 0x83, 0x1b, + 0xd8, 0x61, 0x03, 0x7c, 0x63, 0xad, 0x4f, 0x3c, 0x12, 0x60, 0x4e, 0x7a, 0x8a, 0x72, 0xfb, 0x42, + 0xdf, 0xf7, 0xfb, 0x0e, 0x59, 0x93, 0xa3, 0x6e, 0xb4, 0xb7, 0x46, 0x5c, 0xc6, 0x35, 0x5b, 0xf3, + 0x1f, 0x73, 0xb0, 0xb0, 0x83, 0x3d, 0xba, 0x47, 0x42, 0x6e, 0x91, 0x17, 0x11, 0x09, 0x39, 0x7a, + 0x0e, 0x75, 0x21, 0x8c, 0x51, 0x59, 0xad, 0x5c, 0x9d, 0x5d, 0xdf, 0xee, 0xa4, 0xd2, 0x74, 0x62, + 0x69, 0xe4, 0xc7, 0x8f, 0xed, 0x5e, 0xe7, 0x60, 0xbd, 0xc3, 0xf6, 0xfb, 0x1d, 0x21, 0x4d, 0x27, + 0x23, 0x4d, 0x27, 0x96, 0xa6, 0x63, 0x25, 0xdb, 0xb2, 0x24, 0x55, 0xd4, 0x86, 0x66, 0x40, 0x0e, + 0x68, 0x48, 0x7d, 0xcf, 0xa8, 0xae, 0x56, 0xae, 0xb6, 0xac, 0x64, 0x8c, 0x0c, 0x98, 0xf1, 0xfc, + 0x4d, 0x6c, 0x0f, 0x88, 0x51, 0x5b, 0xad, 0x5c, 0x6d, 0x5a, 0xf1, 0x10, 0xad, 0xc2, 0x2c, 0x66, + 0xec, 0x21, 0xee, 0x12, 0xe7, 0x01, 0x39, 0x34, 0xea, 0x72, 0x61, 0x16, 0x24, 0xd6, 0x62, 0xc6, + 0x1e, 0x61, 0x97, 0x18, 0x0d, 0x39, 0x1b, 0x0f, 0xd1, 0x45, 0x68, 0x79, 0xd8, 0x25, 0x21, 0xc3, + 0x36, 0x31, 0x9a, 0x72, 0x2e, 0x05, 0xa0, 0x9f, 0xc2, 0x52, 0x46, 0xf0, 0x27, 0x7e, 0x14, 0xd8, + 0xc4, 0x00, 0xb9, 0xf5, 0xc7, 0x93, 0x6d, 0x7d, 0xa3, 0x48, 0xd6, 0x1a, 0xe6, 0x84, 0x7e, 0x04, + 0x0d, 0x69, 0x79, 0x63, 0x76, 0xb5, 0xf6, 0x5a, 0xb5, 0xad, 0xc8, 0x22, 0x0f, 0x66, 0x98, 0x13, + 0xf5, 0xa9, 0x17, 0x1a, 0xa7, 0x24, 0x87, 0xa7, 0x93, 0x71, 0xd8, 0xf4, 0xbd, 0x3d, 0xda, 0xdf, + 0xc1, 0x1e, 0xee, 0x13, 0x97, 0x78, 0x7c, 0x57, 0x12, 0xb7, 0x62, 0x26, 0xe8, 0x25, 0x2c, 0xee, + 0x47, 0x21, 0xf7, 0x5d, 0xfa, 0x92, 0x3c, 0x66, 0x62, 0x6d, 0x68, 0xcc, 0x49, 0x6d, 0x3e, 0x9a, + 0x8c, 0xf1, 0x83, 0x02, 0x55, 0x6b, 0x88, 0x8f, 0x70, 0x92, 0xfd, 0xa8, 0x4b, 0x3e, 0x23, 0x81, + 0xf4, 0xae, 0x79, 0xe5, 0x24, 0x19, 0x90, 0x72, 0x23, 0xaa, 0x47, 0xa1, 0xb1, 0xb0, 0x5a, 0x53, + 0x6e, 0x94, 0x80, 0xd0, 0x55, 0x58, 0x38, 0x20, 0x01, 0xdd, 0x3b, 0x7c, 0x42, 0xfb, 0x1e, 0xe6, + 0x51, 0x40, 0x8c, 0x45, 0xe9, 0x8a, 0x45, 0x30, 0x72, 0x61, 0x6e, 0x40, 0x1c, 0x57, 0xa8, 0x7c, + 0x33, 0x20, 0xbd, 0xd0, 0x58, 0x92, 0xfa, 0xdd, 0x9a, 0xdc, 0x82, 0x92, 0x9c, 0x95, 0xa7, 0x2e, + 0x04, 0xf3, 0x7c, 0x4b, 0x47, 0x8a, 0x8a, 0x11, 0xa4, 0x04, 0x2b, 0x80, 0xd1, 0x15, 0x98, 0xe7, + 0x01, 0xb6, 0xf7, 0xa9, 0xd7, 0xdf, 0x21, 0x7c, 0xe0, 0xf7, 0x8c, 0xd3, 0x52, 0x13, 0x05, 0x28, + 0xb2, 0x01, 0x11, 0x0f, 0x77, 0x1d, 0xd2, 0x53, 0xbe, 0xf8, 0xf4, 0x90, 0x91, 0xd0, 0x38, 0x23, + 0x77, 0x71, 0xb3, 0x93, 0xc9, 0x50, 0x85, 0x04, 0xd1, 0xb9, 0x3b, 0xb4, 0xea, 0xae, 0xc7, 0x83, + 0x43, 0xab, 0x84, 0x1c, 0xda, 0x87, 0x59, 0xb1, 0x8f, 0xd8, 0x15, 0xce, 0x4a, 0x57, 0xb8, 0x3f, + 0x99, 0x8e, 0xb6, 0x53, 0x82, 0x56, 0x96, 0x3a, 0xea, 0x00, 0x1a, 0xe0, 0x70, 0x27, 0x72, 0x38, + 0x65, 0x0e, 0x51, 0x62, 0x84, 0xc6, 0xb2, 0x54, 0x53, 0xc9, 0x0c, 0x7a, 0x00, 0x10, 0x90, 0xbd, + 0x18, 0xef, 0x9c, 0xdc, 0xf9, 0xf5, 0x71, 0x3b, 0xb7, 0x12, 0x6c, 0xb5, 0xe3, 0xcc, 0x72, 0xc1, + 0x5c, 0x6c, 0x83, 0xd8, 0x5c, 0x47, 0xbb, 0x0c, 0x6b, 0x43, 0xba, 0x58, 0xc9, 0x8c, 0xf0, 0x45, + 0x0d, 0x95, 0x49, 0xeb, 0xbc, 0xf2, 0xd6, 0x0c, 0x08, 0x6d, 0xc3, 0xd7, 0xb0, 0xe7, 0xf9, 0x5c, + 0x6e, 0x3f, 0x16, 0x65, 0x4b, 0xa7, 0xf7, 0x5d, 0xcc, 0x07, 0xa1, 0xd1, 0x96, 0xab, 0x8e, 0x42, + 0x13, 0x2e, 0x41, 0xbd, 0x90, 0x63, 0xc7, 0x91, 0x48, 0xf7, 0xef, 0x18, 0x17, 0x94, 0x4b, 0xe4, + 0xa1, 0xed, 0xbb, 0x70, 0x6e, 0x84, 0x71, 0xd1, 0x22, 0xd4, 0xf6, 0xc9, 0xa1, 0x3c, 0x14, 0x5a, + 0x96, 0xf8, 0x44, 0x67, 0xa0, 0x71, 0x80, 0x9d, 0x88, 0xc8, 0x34, 0xde, 0xb4, 0xd4, 0xe0, 0x76, + 0xf5, 0x9b, 0x95, 0xf6, 0x2f, 0x2b, 0xb0, 0x50, 0x50, 0x55, 0xc9, 0xfa, 0x1f, 0x66, 0xd7, 0xbf, + 0x86, 0xc0, 0xd9, 0x7b, 0x8a, 0x83, 0x3e, 0xe1, 0x19, 0x41, 0xcc, 0xbf, 0x55, 0xc0, 0x28, 0xd8, + 0xf0, 0x7b, 0x94, 0x0f, 0xee, 0x51, 0x87, 0x84, 0xe8, 0x16, 0xcc, 0x04, 0x0a, 0xa6, 0x8f, 0xba, + 0x0b, 0x63, 0x4c, 0xbf, 0x3d, 0x65, 0xc5, 0xd8, 0xe8, 0x23, 0x68, 0xba, 0x84, 0xe3, 0x1e, 0xe6, + 0x58, 0xcb, 0xbe, 0x5a, 0xb6, 0x52, 0x70, 0xd9, 0xd1, 0x78, 0xdb, 0x53, 0x56, 0xb2, 0x06, 0xbd, + 0x07, 0x0d, 0x7b, 0x10, 0x79, 0xfb, 0xf2, 0x90, 0x9b, 0x5d, 0xbf, 0x34, 0x6a, 0xf1, 0xa6, 0x40, + 0xda, 0x9e, 0xb2, 0x14, 0xf6, 0xc7, 0xd3, 0x50, 0x67, 0x38, 0xe0, 0xe6, 0x3d, 0x38, 0x53, 0xc6, + 0x42, 0x9c, 0xac, 0xf6, 0x80, 0xd8, 0xfb, 0x61, 0xe4, 0x6a, 0x35, 0x27, 0x63, 0x84, 0xa0, 0x1e, + 0xd2, 0x97, 0x4a, 0xd5, 0x35, 0x4b, 0x7e, 0x9b, 0x6f, 0xc3, 0xd2, 0x10, 0x37, 0x61, 0x54, 0x25, + 0x9b, 0xa0, 0x70, 0x4a, 0xb3, 0x36, 0x23, 0x38, 0xfb, 0x54, 0xea, 0x22, 0x39, 0x5e, 0x4e, 0xa2, + 0x56, 0x30, 0xb7, 0x61, 0xb9, 0xc8, 0x36, 0x64, 0xbe, 0x17, 0x12, 0x11, 0x6c, 0x32, 0x1f, 0x53, + 0xd2, 0x4b, 0x67, 0xa5, 0x14, 0x4d, 0xab, 0x64, 0xc6, 0xfc, 0x6d, 0x15, 0x96, 0x2d, 0x12, 0xfa, + 0xce, 0x01, 0x89, 0x93, 0xe5, 0xc9, 0x94, 0x3b, 0x3f, 0x80, 0x1a, 0x66, 0x4c, 0xbb, 0xc9, 0xfd, + 0xd7, 0x56, 0x50, 0x58, 0x82, 0x2a, 0x7a, 0x07, 0x96, 0xb0, 0xdb, 0xa5, 0xfd, 0xc8, 0x8f, 0xc2, + 0x78, 0x5b, 0xd2, 0xa9, 0x5a, 0xd6, 0xf0, 0x84, 0x48, 0x38, 0xa1, 0x8c, 0xc8, 0xfb, 0x5e, 0x8f, + 0xfc, 0x44, 0xd6, 0x50, 0x35, 0x2b, 0x0b, 0x32, 0x6d, 0x38, 0x37, 0xa4, 0x24, 0xad, 0xf0, 0x6c, + 0xd9, 0x56, 0x29, 0x94, 0x6d, 0xa5, 0x62, 0x54, 0x47, 0x88, 0x61, 0xbe, 0xaa, 0xc0, 0x62, 0x1a, + 0x5c, 0x9a, 0xfc, 0x45, 0x68, 0xb9, 0x1a, 0x16, 0x1a, 0x15, 0x99, 0x33, 0x53, 0x40, 0xbe, 0x82, + 0xab, 0x16, 0x2b, 0xb8, 0x65, 0x98, 0x56, 0x05, 0xb6, 0xde, 0xba, 0x1e, 0xe5, 0x44, 0xae, 0x17, + 0x44, 0x5e, 0x01, 0x08, 0x93, 0x0c, 0x67, 0x4c, 0xcb, 0xd9, 0x0c, 0x04, 0x99, 0x70, 0x4a, 0x9d, + 0xf7, 0x16, 0x09, 0x23, 0x87, 0x1b, 0x33, 0x12, 0x23, 0x07, 0x93, 0xf1, 0xe6, 0xbb, 0x2e, 0xf6, + 0x7a, 0xa1, 0xd1, 0x94, 0x22, 0x27, 0x63, 0xd3, 0x87, 0x85, 0x87, 0x54, 0xec, 0x6f, 0x2f, 0x3c, + 0x99, 0x50, 0x79, 0x1f, 0xea, 0x82, 0x99, 0x10, 0xaa, 0x1b, 0x60, 0xcf, 0x1e, 0x90, 0x58, 0x8f, + 0xc9, 0x58, 0x24, 0x01, 0x8e, 0xfb, 0xa1, 0x51, 0x95, 0x70, 0xf9, 0x6d, 0xfe, 0xbe, 0xaa, 0x24, + 0xdd, 0x60, 0x2c, 0xfc, 0xea, 0x1b, 0x80, 0xf2, 0x92, 0xa4, 0x36, 0x5c, 0x92, 0x14, 0x44, 0xfe, + 0x32, 0x25, 0xc9, 0x6b, 0x3a, 0xe4, 0xcc, 0x08, 0x66, 0x36, 0x18, 0x13, 0x82, 0xa0, 0x1b, 0x50, + 0xc7, 0x8c, 0x29, 0x85, 0x17, 0xf2, 0xb9, 0x46, 0x11, 0xff, 0xb5, 0x48, 0x12, 0xb5, 0x7d, 0x0b, + 0x5a, 0x09, 0xe8, 0x28, 0xb6, 0xad, 0x2c, 0xdb, 0x55, 0x00, 0x55, 0x73, 0xdf, 0xf7, 0xf6, 0x7c, + 0x61, 0x52, 0x11, 0x08, 0x7a, 0xa9, 0xfc, 0x36, 0x6f, 0xc7, 0x18, 0x52, 0xb6, 0x77, 0xa0, 0x41, + 0x39, 0x71, 0x63, 0xe1, 0x96, 0xb3, 0xc2, 0xa5, 0x84, 0x2c, 0x85, 0x64, 0xfe, 0xb9, 0x09, 0xe7, + 0x85, 0xc5, 0x9e, 0xc8, 0x10, 0xda, 0x60, 0xec, 0x0e, 0xe1, 0x98, 0x3a, 0xe1, 0x77, 0x23, 0x12, + 0x1c, 0xbe, 0x61, 0xc7, 0xe8, 0xc3, 0xb4, 0x8a, 0x40, 0x9d, 0x2d, 0x5f, 0x7b, 0xfb, 0xa5, 0xc9, + 0xa7, 0x3d, 0x57, 0xed, 0xcd, 0xf4, 0x5c, 0x65, 0x3d, 0x50, 0xfd, 0x84, 0x7a, 0xa0, 0xd1, 0x6d, + 0x70, 0xa6, 0xb9, 0x9e, 0xce, 0x37, 0xd7, 0x25, 0xad, 0xc5, 0xcc, 0x71, 0x5b, 0x8b, 0x66, 0x69, + 0x6b, 0xe1, 0x96, 0xc6, 0x71, 0x4b, 0xaa, 0xfb, 0xdb, 0x59, 0x0f, 0x1c, 0xe9, 0x6b, 0x93, 0x34, + 0x19, 0xf0, 0x46, 0x9b, 0x8c, 0x4f, 0x73, 0x4d, 0x83, 0x6a, 0xdb, 0xdf, 0x3b, 0xde, 0x9e, 0xc6, + 0xb4, 0x0f, 0xff, 0x77, 0xa5, 0xf7, 0x2f, 0x64, 0xc5, 0xc5, 0xfc, 0x54, 0x07, 0xc9, 0x61, 0x2f, + 0xce, 0x21, 0x71, 0xec, 0xea, 0xa4, 0x25, 0xbe, 0xd1, 0x75, 0xa8, 0x0b, 0x25, 0xeb, 0x92, 0xf8, + 0x5c, 0x56, 0x9f, 0xc2, 0x12, 0x1b, 0x8c, 0x3d, 0x61, 0xc4, 0xb6, 0x24, 0x12, 0xba, 0x0d, 0xad, + 0xc4, 0xf1, 0x75, 0x64, 0x5d, 0xcc, 0xae, 0x48, 0xe2, 0x24, 0x5e, 0x96, 0xa2, 0x8b, 0xb5, 0x3d, + 0x1a, 0x10, 0x5b, 0x16, 0x8c, 0x8d, 0xe1, 0xb5, 0x77, 0xe2, 0xc9, 0x64, 0x6d, 0x82, 0x8e, 0x6e, + 0xc0, 0xb4, 0xba, 0xe7, 0x90, 0x11, 0x34, 0xbb, 0x7e, 0x7e, 0x38, 0x99, 0xc6, 0xab, 0x34, 0xa2, + 0xf9, 0xa7, 0x0a, 0xbc, 0x95, 0x3a, 0x44, 0x1c, 0x4d, 0x71, 0xcd, 0xfe, 0xd5, 0x9f, 0xb8, 0x57, + 0x60, 0x5e, 0x36, 0x09, 0xe9, 0x75, 0x87, 0xba, 0x79, 0x2b, 0x40, 0xcd, 0xdf, 0x55, 0xe0, 0xf2, + 0xf0, 0x3e, 0x36, 0x07, 0x38, 0xe0, 0x89, 0x79, 0x4f, 0x62, 0x2f, 0xf1, 0x81, 0x57, 0x4d, 0x0f, + 0xbc, 0xdc, 0xfe, 0x6a, 0xf9, 0xfd, 0x99, 0x7f, 0xa8, 0xc2, 0x6c, 0xc6, 0x81, 0xca, 0x0e, 0x4c, + 0x51, 0x0c, 0x4a, 0xbf, 0x95, 0x6d, 0xa1, 0x3c, 0x14, 0x5a, 0x56, 0x06, 0x82, 0xf6, 0x01, 0x18, + 0x0e, 0xb0, 0x4b, 0x38, 0x09, 0x44, 0x26, 0x17, 0x11, 0xff, 0x60, 0xf2, 0xec, 0xb2, 0x1b, 0xd3, + 0xb4, 0x32, 0xe4, 0x45, 0x35, 0x2b, 0x59, 0x87, 0x3a, 0x7f, 0xeb, 0x11, 0xfa, 0x02, 0xe6, 0xf7, + 0xa8, 0x43, 0x76, 0x53, 0x41, 0xa6, 0xa5, 0x20, 0x8f, 0x27, 0x17, 0xe4, 0x5e, 0x96, 0xae, 0x55, + 0x60, 0x63, 0x5e, 0x83, 0xc5, 0x62, 0x3c, 0x09, 0x21, 0xa9, 0x8b, 0xfb, 0x89, 0xb6, 0xf4, 0xc8, + 0x44, 0xb0, 0x58, 0x8c, 0x1f, 0xf3, 0x9f, 0x55, 0x38, 0x9b, 0x90, 0xdb, 0xf0, 0x3c, 0x3f, 0xf2, + 0x6c, 0x79, 0x75, 0x58, 0x6a, 0x8b, 0x33, 0xd0, 0xe0, 0x94, 0x3b, 0x49, 0xe1, 0x23, 0x07, 0xe2, + 0xec, 0xe2, 0xbe, 0xef, 0x70, 0xca, 0xb4, 0x81, 0xe3, 0xa1, 0xb2, 0xfd, 0x8b, 0x88, 0x06, 0xa4, + 0x27, 0x33, 0x41, 0xd3, 0x4a, 0xc6, 0x62, 0x4e, 0x54, 0x35, 0xb2, 0xc4, 0x57, 0xca, 0x4c, 0xc6, + 0xd2, 0xef, 0x7d, 0xc7, 0x21, 0xb6, 0x50, 0x47, 0xa6, 0x09, 0x28, 0x40, 0x65, 0x73, 0xc1, 0x03, + 0xea, 0xf5, 0x75, 0x0b, 0xa0, 0x47, 0x42, 0x4e, 0x1c, 0x04, 0xf8, 0x50, 0x57, 0xfe, 0x6a, 0x80, + 0x3e, 0x84, 0x9a, 0x8b, 0x99, 0x3e, 0xe8, 0xae, 0xe5, 0xb2, 0x43, 0x99, 0x06, 0x3a, 0x3b, 0x98, + 0xa9, 0x93, 0x40, 0x2c, 0x6b, 0xbf, 0x0f, 0xcd, 0x18, 0xf0, 0xa5, 0x4a, 0xc2, 0xcf, 0x61, 0x2e, + 0x97, 0x7c, 0xd0, 0x33, 0x58, 0x4e, 0x3d, 0x2a, 0xcb, 0x50, 0x17, 0x81, 0x6f, 0x1d, 0x29, 0x99, + 0x35, 0x82, 0x80, 0xf9, 0x02, 0x96, 0x84, 0xcb, 0xc8, 0xc0, 0x3f, 0xa1, 0xd6, 0xe6, 0x03, 0x68, + 0x25, 0x2c, 0x4b, 0x7d, 0xa6, 0x0d, 0xcd, 0x83, 0xf8, 0x4a, 0x57, 0xf5, 0x36, 0xc9, 0xd8, 0xdc, + 0x00, 0x94, 0x95, 0x57, 0x9f, 0x40, 0xd7, 0xf3, 0x45, 0xf1, 0xd9, 0xe2, 0x71, 0x23, 0xd1, 0xe3, + 0x9a, 0xf8, 0xef, 0x55, 0x58, 0xd8, 0xa2, 0xf2, 0x8e, 0xe4, 0x84, 0x92, 0xdc, 0x35, 0x58, 0x0c, + 0xa3, 0xae, 0xeb, 0xf7, 0x22, 0x87, 0xe8, 0xa2, 0x40, 0x9f, 0xf4, 0x43, 0xf0, 0x71, 0xc9, 0x4f, + 0x28, 0x8b, 0x61, 0x3e, 0xd0, 0xdd, 0xaf, 0xfc, 0x46, 0x1f, 0xc2, 0xf9, 0x47, 0xe4, 0x0b, 0xbd, + 0x9f, 0x2d, 0xc7, 0xef, 0x76, 0xa9, 0xd7, 0x8f, 0x99, 0x34, 0x24, 0x93, 0xd1, 0x08, 0x65, 0xa5, + 0xe2, 0x74, 0x79, 0xa9, 0x98, 0x74, 0xd0, 0x9b, 0xbe, 0xeb, 0x52, 0xae, 0x2b, 0xca, 0x1c, 0xcc, + 0xfc, 0x79, 0x05, 0x16, 0x53, 0xcd, 0x6a, 0xdb, 0xdc, 0x52, 0x31, 0xa4, 0x2c, 0x73, 0x39, 0x6b, + 0x99, 0x22, 0xea, 0x7f, 0x1e, 0x3e, 0xa7, 0xb2, 0xe1, 0xf3, 0xab, 0x2a, 0x9c, 0xdd, 0xa2, 0x3c, + 0x4e, 0x5c, 0xf4, 0x7f, 0xcd, 0xca, 0x25, 0x36, 0xa9, 0x1f, 0xcf, 0x26, 0x8d, 0x12, 0x9b, 0x74, + 0x60, 0xb9, 0xa8, 0x0c, 0x6d, 0x98, 0x33, 0xd0, 0x60, 0xf2, 0xd2, 0x59, 0xdd, 0x2b, 0xa8, 0x81, + 0xf9, 0xb3, 0x19, 0xb8, 0xf4, 0x29, 0xeb, 0x61, 0x9e, 0xdc, 0x19, 0xdd, 0xf3, 0x03, 0x79, 0xeb, + 0x7c, 0x32, 0x5a, 0x2c, 0xbc, 0x0c, 0x56, 0xc7, 0xbe, 0x0c, 0xd6, 0xc6, 0xbc, 0x0c, 0xd6, 0x8f, + 0xf5, 0x32, 0xd8, 0x38, 0xb1, 0x97, 0xc1, 0xe1, 0x5e, 0x6b, 0xba, 0xb4, 0xd7, 0x7a, 0x96, 0xeb, + 0x47, 0x66, 0x64, 0xd8, 0x7c, 0x2b, 0x1b, 0x36, 0x63, 0xad, 0x33, 0xf6, 0x49, 0xa3, 0xf0, 0xa0, + 0xd6, 0x3c, 0xf2, 0x41, 0xad, 0x35, 0xfc, 0xa0, 0x56, 0xfe, 0x26, 0x03, 0x23, 0xdf, 0x64, 0xae, + 0xc0, 0x7c, 0x78, 0xe8, 0xd9, 0xa4, 0x97, 0xdc, 0x24, 0xce, 0xaa, 0x6d, 0xe7, 0xa1, 0xb9, 0x88, + 0x38, 0x55, 0x88, 0x88, 0xc4, 0x53, 0xe7, 0x32, 0x9e, 0x5a, 0x16, 0x27, 0xf3, 0x23, 0xdb, 0xdc, + 0xc2, 0x73, 0xc9, 0x42, 0xe9, 0x73, 0xc9, 0x7f, 0x4d, 0xb3, 0xf5, 0x19, 0xac, 0x8c, 0xb2, 0xb2, + 0x0e, 0x5e, 0x03, 0x66, 0xec, 0x01, 0xf6, 0xfa, 0xf2, 0x5a, 0x50, 0x76, 0xff, 0x7a, 0x38, 0xae, + 0x3b, 0x58, 0xff, 0x23, 0xc0, 0x52, 0x5a, 0xf5, 0x8b, 0xbf, 0xd4, 0x26, 0xe8, 0x31, 0x2c, 0xc6, + 0xcf, 0x4b, 0xf1, 0x45, 0x2e, 0x1a, 0xf7, 0x76, 0xd2, 0xbe, 0x58, 0x3e, 0xa9, 0x44, 0x33, 0xa7, + 0x90, 0x0d, 0xe7, 0x8b, 0x04, 0xd3, 0x67, 0x9a, 0x6f, 0x8c, 0xa1, 0x9c, 0x60, 0x1d, 0xc5, 0xe2, + 0x6a, 0x05, 0x3d, 0x83, 0xf9, 0xfc, 0x63, 0x02, 0xca, 0x95, 0x41, 0xa5, 0xef, 0x1b, 0x6d, 0x73, + 0x1c, 0x4a, 0x22, 0xff, 0x73, 0xe1, 0x06, 0xb9, 0x7b, 0x73, 0x64, 0xe6, 0x6f, 0x04, 0xca, 0x5e, + 0x1e, 0xda, 0x5f, 0x1f, 0x8b, 0x93, 0x50, 0xff, 0x00, 0x9a, 0xf1, 0x5d, 0x72, 0x5e, 0xcd, 0x85, + 0x1b, 0xe6, 0xf6, 0x62, 0x9e, 0xde, 0x5e, 0x68, 0x4e, 0xa1, 0x8f, 0xd4, 0xe2, 0x0d, 0xc6, 0x4a, + 0x16, 0x67, 0x6e, 0x50, 0xdb, 0xa7, 0x4b, 0x6e, 0x2d, 0xcd, 0x29, 0xf4, 0x1d, 0x98, 0x15, 0x5f, + 0xbb, 0xfa, 0x79, 0x7f, 0xb9, 0xa3, 0x7e, 0x4d, 0xd2, 0x89, 0x7f, 0x4d, 0xd2, 0xb9, 0xeb, 0x32, + 0x7e, 0xd8, 0x2e, 0xb9, 0x56, 0xd4, 0x04, 0x9e, 0xc3, 0xdc, 0x16, 0xe1, 0xe9, 0x2d, 0x00, 0xba, + 0x7c, 0xac, 0xbb, 0x92, 0xb6, 0x59, 0x44, 0x1b, 0xbe, 0x48, 0x30, 0xa7, 0xd0, 0xaf, 0x2b, 0x70, + 0x7a, 0x8b, 0xf0, 0x62, 0x5f, 0x8d, 0xde, 0x2d, 0x67, 0x32, 0xa2, 0xff, 0x6e, 0x3f, 0x9a, 0x34, + 0x26, 0xf3, 0x64, 0xcd, 0x29, 0xf4, 0x9b, 0x0a, 0x9c, 0xcb, 0x08, 0x96, 0x6d, 0x94, 0xd1, 0x8d, + 0xf1, 0xc2, 0x95, 0x34, 0xd5, 0xed, 0x4f, 0x26, 0xfc, 0xd5, 0x46, 0x86, 0xa4, 0x39, 0x85, 0x76, + 0xa5, 0x4d, 0xd2, 0xba, 0x18, 0x5d, 0x2a, 0x2d, 0x80, 0x13, 0xee, 0x2b, 0xa3, 0xa6, 0x13, 0x3b, + 0x7c, 0x02, 0xb3, 0x5b, 0x84, 0xc7, 0x05, 0x5a, 0xde, 0xd3, 0x0a, 0xb5, 0x73, 0x3e, 0x54, 0x8b, + 0x35, 0x9d, 0xf4, 0x98, 0x25, 0x45, 0x2b, 0x53, 0x84, 0xe4, 0x63, 0xb5, 0xb4, 0x5a, 0xcb, 0x7b, + 0x4c, 0x79, 0x0d, 0x63, 0x4e, 0xa1, 0x17, 0xb0, 0x5c, 0x9e, 0x2a, 0xd1, 0xdb, 0xc7, 0x3e, 0x34, + 0xdb, 0xd7, 0x8e, 0x83, 0x1a, 0xb3, 0xfc, 0x78, 0xe3, 0x2f, 0xaf, 0x56, 0x2a, 0x7f, 0x7d, 0xb5, + 0x52, 0xf9, 0xd7, 0xab, 0x95, 0xca, 0xf7, 0x6f, 0x1e, 0xf1, 0xeb, 0xae, 0xcc, 0x0f, 0xc6, 0x30, + 0xa3, 0xb6, 0x43, 0x89, 0xc7, 0xbb, 0xd3, 0x32, 0xde, 0x6e, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, + 0xa5, 0xe0, 0xaa, 0x70, 0x4f, 0x26, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3233,6 +3265,24 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.InstallationID) > 0 { + i -= len(m.InstallationID) + copy(dAtA[i:], m.InstallationID) + i = encodeVarintRepository(dAtA, i, uint64(len(m.InstallationID))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xda + } + if len(m.AnnotationManifestGeneratePaths) > 0 { + i -= len(m.AnnotationManifestGeneratePaths) + copy(dAtA[i:], m.AnnotationManifestGeneratePaths) + i = encodeVarintRepository(dAtA, i, uint64(len(m.AnnotationManifestGeneratePaths))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } if len(m.ProjectName) > 0 { i -= len(m.ProjectName) copy(dAtA[i:], m.ProjectName) @@ -5257,6 +5307,13 @@ func (m *UpdateRevisionForPathsRequest) MarshalToSizedBuffer(dAtA []byte) (int, i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.InstallationID) > 0 { + i -= len(m.InstallationID) + copy(dAtA[i:], m.InstallationID) + i = encodeVarintRepository(dAtA, i, uint64(len(m.InstallationID))) + i-- + dAtA[i] = 0x7a + } if m.NoRevisionCache { i-- if m.NoRevisionCache { @@ -5565,6 +5622,14 @@ func (m *ManifestRequest) Size() (n int) { if l > 0 { n += 2 + l + sovRepository(uint64(l)) } + l = len(m.AnnotationManifestGeneratePaths) + if l > 0 { + n += 2 + l + sovRepository(uint64(l)) + } + l = len(m.InstallationID) + if l > 0 { + n += 2 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6424,6 +6489,10 @@ func (m *UpdateRevisionForPathsRequest) Size() (n int) { if m.NoRevisionCache { n += 2 } + l = len(m.InstallationID) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7342,6 +7411,70 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error { } m.ProjectName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AnnotationManifestGeneratePaths", 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.AnnotationManifestGeneratePaths = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 27: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstallationID", 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.InstallationID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -12678,6 +12811,38 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { } } m.NoRevisionCache = bool(v != 0) + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InstallationID", 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.InstallationID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/cache/cache.go b/reposerver/cache/cache.go index fde5a81748ab0..cdc16ea4ebb82 100644 --- a/reposerver/cache/cache.go +++ b/reposerver/cache/cache.go @@ -290,13 +290,17 @@ func (c *Cache) UnlockGitReferences(repo string, lockId string) error { // refSourceCommitSHAs is a list of resolved revisions for each ref source. This allows us to invalidate the cache // when someone pushes a commit to a source which is referenced from the main source (the one referred to by `revision`). -func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, namespace string, trackingMethod string, appLabelKey string, appName string, info ClusterRuntimeInfo, refSourceCommitSHAs ResolvedRevisions) string { +func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, namespace string, trackingMethod string, appLabelKey string, appName string, info ClusterRuntimeInfo, refSourceCommitSHAs ResolvedRevisions, installationID string) string { // TODO: this function is getting unwieldy. We should probably consolidate some of this stuff into a struct. For // example, revision could be part of ResolvedRevisions. And srcRefs is probably redundant now that // refSourceCommitSHAs has been added. We don't need to know the _target_ revisions of the referenced sources // when the _resolved_ revisions are already part of the key. trackingKey := trackingKey(appLabelKey, trackingMethod) - return fmt.Sprintf("mfst|%s|%s|%s|%s|%d", trackingKey, appName, revision, namespace, appSourceKey(appSrc, srcRefs, refSourceCommitSHAs)+clusterRuntimeInfoKey(info)) + key := fmt.Sprintf("mfst|%s|%s|%s|%s|%d", trackingKey, appName, revision, namespace, appSourceKey(appSrc, srcRefs, refSourceCommitSHAs)+clusterRuntimeInfoKey(info)) + if installationID != "" { + key = fmt.Sprintf("%s|%s", key, installationID) + } + return key } func trackingKey(appLabelKey string, trackingMethod string) string { @@ -323,14 +327,14 @@ func LogDebugManifestCacheKeyFields(message string, reason string, revision stri } } -func (c *Cache) SetNewRevisionManifests(newRevision string, revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, refSourceCommitSHAs ResolvedRevisions) error { - oldKey := manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs) - newKey := manifestCacheKey(newRevision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs) +func (c *Cache) SetNewRevisionManifests(newRevision string, revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, refSourceCommitSHAs ResolvedRevisions, installationID string) error { + oldKey := manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs, installationID) + newKey := manifestCacheKey(newRevision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs, installationID) return c.cache.RenameItem(oldKey, newKey, c.repoCacheExpiration) } -func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse, refSourceCommitSHAs ResolvedRevisions) error { - err := c.cache.GetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs), res) +func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse, refSourceCommitSHAs ResolvedRevisions, installationID string) error { + err := c.cache.GetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs, installationID), res) if err != nil { return err } @@ -346,7 +350,7 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, s LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", revision, appSrc, srcRefs, clusterInfo, namespace, trackingMethod, appLabelKey, appName, refSourceCommitSHAs) - err = c.DeleteManifests(revision, appSrc, srcRefs, clusterInfo, namespace, trackingMethod, appLabelKey, appName, refSourceCommitSHAs) + err = c.DeleteManifests(revision, appSrc, srcRefs, clusterInfo, namespace, trackingMethod, appLabelKey, appName, refSourceCommitSHAs, installationID) if err != nil { return fmt.Errorf("Unable to delete manifest after hash mismatch, %w", err) } @@ -366,7 +370,7 @@ func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, s return nil } -func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse, refSourceCommitSHAs ResolvedRevisions) error { +func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse, refSourceCommitSHAs ResolvedRevisions, installationID string) error { // Generate and apply the cache entry hash, before writing if res != nil { res = res.shallowCopy() @@ -378,7 +382,7 @@ func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, s } return c.cache.SetItem( - manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs), + manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs, installationID), res, &cacheutil.CacheActionOpts{ Expiration: c.repoCacheExpiration, @@ -386,9 +390,9 @@ func (c *Cache) SetManifests(revision string, appSrc *appv1.ApplicationSource, s }) } -func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace, trackingMethod, appLabelKey, appName string, refSourceCommitSHAs ResolvedRevisions) error { +func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace, trackingMethod, appLabelKey, appName string, refSourceCommitSHAs ResolvedRevisions, installationID string) error { return c.cache.SetItem( - manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs), + manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs, installationID), "", &cacheutil.CacheActionOpts{Delete: true}) } diff --git a/reposerver/cache/cache_test.go b/reposerver/cache/cache_test.go index 82e7fd556ad16..a42ac0a513239 100644 --- a/reposerver/cache/cache_test.go +++ b/reposerver/cache/cache_test.go @@ -94,43 +94,43 @@ func TestCache_GetManifests(t *testing.T) { // cache miss q := &apiclient.ManifestRequest{} value := &CachedManifestResponse{} - err := cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) + err := cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) // populate cache res := &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}} - err = cache.SetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", res, nil) + err = cache.SetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", res, nil, "") require.NoError(t, err) t.Run("expect cache miss because of changed revision", func(t *testing.T) { - err = cache.GetManifests("other-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) + err = cache.GetManifests("other-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache miss because of changed path", func(t *testing.T) { - err = cache.GetManifests("my-revision", &ApplicationSource{Path: "other-path"}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) + err = cache.GetManifests("my-revision", &ApplicationSource{Path: "other-path"}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache miss because of changed namespace", func(t *testing.T) { - err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "other-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "other-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache miss because of changed app label key", func(t *testing.T) { - err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "other-app-label-key", "my-app-label-value", value, nil) + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "other-app-label-key", "my-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache miss because of changed app label value", func(t *testing.T) { - err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, nil) + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, nil, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache miss because of changed referenced source", func(t *testing.T) { - err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, map[string]string{"my-referenced-source": "my-referenced-revision"}) + err = cache.GetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "other-app-label-value", value, map[string]string{"my-referenced-source": "my-referenced-revision"}, "") assert.Equal(t, ErrCacheMiss, err) }) t.Run("expect cache hit", func(t *testing.T) { err = cache.SetManifests( "my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", - &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type", Revision: "my-revision2"}}, nil) + &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type", Revision: "my-revision2"}}, nil, "") require.NoError(t, err) - err = cache.GetManifests("my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) + err = cache.GetManifests("my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil, "") require.NoError(t, err) assert.Equal(t, "my-source-type", value.ManifestResponse.SourceType) @@ -199,7 +199,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { NumberOfConsecutiveFailures: 0, } q := &apiclient.ManifestRequest{} - err := repoCache.SetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, store, nil) + err := repoCache.SetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, store, nil, "") if err != nil { t.Fatal(err) } @@ -229,7 +229,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { // Retrieve the value using 'GetManifests' and confirm it works retrievedVal := &CachedManifestResponse{} - err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal, nil) + err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal, nil, "") if err != nil { t.Fatal(err) } @@ -251,7 +251,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { // Retrieve the value using GetManifests and confirm it returns a cache miss retrievedVal = &CachedManifestResponse{} - err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal, nil) + err = repoCache.GetManifests(response.Revision, appSrc, q.RefSources, q, response.Namespace, "", appKey, appValue, retrievedVal, nil, "") assert.Equal(t, err, cacheutil.ErrCacheMiss) @@ -261,6 +261,7 @@ func TestCachedManifestResponse_HashBehavior(t *testing.T) { } func getInMemoryCacheContents(t *testing.T, inMemCache *cacheutil.InMemoryCache) map[string]*CachedManifestResponse { + t.Helper() items, err := inMemCache.Items(func() interface{} { return &CachedManifestResponse{} }) if err != nil { t.Fatal(err) @@ -570,8 +571,7 @@ func TestUnlockGitReferences(t *testing.T) { t.Run("Test not locked", func(t *testing.T) { err := cache.UnlockGitReferences("test-repo", "") - require.Error(t, err) - assert.Contains(t, err.Error(), "key is missing") + assert.ErrorContains(t, err, "key is missing") }) t.Run("Test unlock", func(t *testing.T) { diff --git a/reposerver/cache/mocks/reposervercache.go b/reposerver/cache/mocks/reposervercache.go index f26bd8bccac43..ddc71510e7698 100644 --- a/reposerver/cache/mocks/reposervercache.go +++ b/reposerver/cache/mocks/reposervercache.go @@ -41,6 +41,7 @@ type CacheCallCounts struct { // Checks that the cache was called the expected number of times func (mockCache *MockRepoCache) AssertCacheCalledTimes(t *testing.T, calls *CacheCallCounts) { + t.Helper() mockCache.RedisClient.AssertNumberOfCalls(t, "Get", calls.ExternalGets) mockCache.RedisClient.AssertNumberOfCalls(t, "Set", calls.ExternalSets) mockCache.RedisClient.AssertNumberOfCalls(t, "Delete", calls.ExternalDeletes) diff --git a/reposerver/metrics/githandlers_test.go b/reposerver/metrics/githandlers_test.go index 6eaeeca82cc36..e2eb03dca1d48 100644 --- a/reposerver/metrics/githandlers_test.go +++ b/reposerver/metrics/githandlers_test.go @@ -22,6 +22,7 @@ func TestEdgeCasesAndErrorHandling(t *testing.T) { { name: "lsRemoteParallelismLimitSemaphore is nil", testFunc: func(t *testing.T) { + t.Helper() lsRemoteParallelismLimitSemaphore = nil assert.NotPanics(t, func() { NewGitClientEventHandlers(&MetricsServer{}) @@ -37,6 +38,7 @@ func TestEdgeCasesAndErrorHandling(t *testing.T) { lsRemoteParallelismLimitSemaphore = nil }, testFunc: func(t *testing.T) { + t.Helper() assert.NotPanics(t, func() { NewGitClientEventHandlers(&MetricsServer{}) }) @@ -51,6 +53,7 @@ func TestEdgeCasesAndErrorHandling(t *testing.T) { lsRemoteParallelismLimitSemaphore = nil }, testFunc: func(t *testing.T) { + t.Helper() assert.NotPanics(t, func() { NewGitClientEventHandlers(&MetricsServer{}) }) @@ -88,6 +91,7 @@ func TestSemaphoreFunctionality(t *testing.T) { lsRemoteParallelismLimitSemaphore = nil }, testFunc: func(t *testing.T) { + t.Helper() assert.NotPanics(t, func() { NewGitClientEventHandlers(&MetricsServer{}) }) @@ -102,6 +106,7 @@ func TestSemaphoreFunctionality(t *testing.T) { lsRemoteParallelismLimitSemaphore = nil }, testFunc: func(t *testing.T) { + t.Helper() assert.NotPanics(t, func() { NewGitClientEventHandlers(&MetricsServer{}) }) diff --git a/reposerver/repository/chart.go b/reposerver/repository/chart.go index c1ad7855049d3..3424db4b51fcd 100644 --- a/reposerver/repository/chart.go +++ b/reposerver/repository/chart.go @@ -20,7 +20,7 @@ func getChartDetails(chartYAML string) (*v1alpha1.ChartDetails, error) { if maintainer.Email != "" { maintainers = append(maintainers, strings.Trim(fmt.Sprintf("%v <%v>", maintainer.Name, maintainer.Email), " ")) } else { - maintainers = append(maintainers, fmt.Sprintf("%v", maintainer.Name)) + maintainers = append(maintainers, maintainer.Name) } } return &v1alpha1.ChartDetails{ diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index e387a5bf93380..11bc154d4f69c 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -31,6 +31,8 @@ import ( "golang.org/x/sync/semaphore" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -113,6 +115,7 @@ type RepoServerInitConstants struct { HelmRegistryMaxIndexSize int64 DisableHelmManifestMaxExtractedSize bool IncludeHiddenDirectories bool + CMPUseManifestGeneratePaths bool } // NewService returns a new instance of the Manifest service @@ -805,7 +808,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, } } - manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs)) + manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs), WithCMPUseManifestGeneratePaths(s.initConstants.CMPUseManifestGeneratePaths)) } refSourceCommitSHAs := make(map[string]string) if len(repoRefs) > 0 { @@ -826,7 +829,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, // Retrieve a new copy (if available) of the cached response: this ensures we are updating the latest copy of the cache, // rather than a copy of the cache that occurred before (a potentially lengthy) manifest generation. innerRes := &cache.CachedManifestResponse{} - cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes, refSourceCommitSHAs) + cacheErr := s.cache.GetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes, refSourceCommitSHAs, q.InstallationID) if cacheErr != nil && !errors.Is(cacheErr, cache.ErrCacheMiss) { logCtx.Warnf("manifest cache get error %s: %v", appSourceCopy.String(), cacheErr) ch.errCh <- cacheErr @@ -844,7 +847,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, // Update the cache to include failure information innerRes.NumberOfConsecutiveFailures++ innerRes.MostRecentError = err.Error() - cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes, refSourceCommitSHAs) + cacheErr = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, innerRes, refSourceCommitSHAs, q.InstallationID) if cacheErr != nil { logCtx.Warnf("manifest cache set error %s: %v", appSourceCopy.String(), cacheErr) @@ -868,7 +871,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, } manifestGenResult.Revision = commitSHA manifestGenResult.VerifyResult = opContext.verificationResult - err = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry, refSourceCommitSHAs) + err = s.cache.SetManifests(cacheKey, appSourceCopy, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &manifestGenCacheEntry, refSourceCommitSHAs, q.InstallationID) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", appSourceCopy.String(), cacheKey, err) } @@ -885,7 +888,7 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe cache.LogDebugManifestCacheKeyFields("getting manifests cache", "GenerateManifest API call", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs) res := cache.CachedManifestResponse{} - err := s.cache.GetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res, refSourceCommitSHAs) + err := s.cache.GetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res, refSourceCommitSHAs, q.InstallationID) if err == nil { // The cache contains an existing value @@ -902,7 +905,7 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "manifest hash did not match or cached response is empty", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs) // We can now try again, so reset the cache state and run the operation below - err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs) + err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs, q.InstallationID) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -917,7 +920,7 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe cache.LogDebugManifestCacheKeyFields("deleting manifests cache", "reset after paused generation count", cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs) // We can now try again, so reset the error cache state and run the operation below - err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs) + err = s.cache.DeleteManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, refSourceCommitSHAs, q.InstallationID) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -937,7 +940,7 @@ func (s *Service) getManifestCacheEntry(cacheKey string, q *apiclient.ManifestRe // Increment the number of returned cached responses and push that new value to the cache // (if we have not already done so previously in this function) res.NumberOfCachedResponsesReturned++ - err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res, refSourceCommitSHAs) + err = s.cache.SetManifests(cacheKey, q.ApplicationSource, q.RefSources, q, q.Namespace, q.TrackingMethod, q.AppLabelKey, q.AppName, &res, refSourceCommitSHAs, q.InstallationID) if err != nil { log.Warnf("manifest cache set error %s/%s: %v", q.ApplicationSource.String(), cacheKey, err) } @@ -1135,6 +1138,9 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie if appHelm.ReleaseName != "" { templateOpts.Name = appHelm.ReleaseName } + if appHelm.Namespace != "" { + templateOpts.Namespace = appHelm.Namespace + } resolvedValueFiles, err := getResolvedValueFiles(appPath, repoRoot, env, q.GetValuesFileSchemes(), appHelm.ValueFiles, q.RefSources, gitRepoPaths, appHelm.IgnoreMissingValueFiles) if err != nil { @@ -1188,6 +1194,8 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie } passCredentials = appHelm.PassCredentials templateOpts.SkipCrds = appHelm.SkipCrds + templateOpts.SkipSchemaValidation = appHelm.SkipSchemaValidation + templateOpts.SkipTests = appHelm.SkipTests } if templateOpts.Name == "" { templateOpts.Name = q.AppName @@ -1376,8 +1384,9 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v type ( GenerateManifestOpt func(*generateManifestOpt) generateManifestOpt struct { - cmpTarDoneCh chan<- bool - cmpTarExcludedGlobs []string + cmpTarDoneCh chan<- bool + cmpTarExcludedGlobs []string + cmpUseManifestGeneratePaths bool } ) @@ -1406,6 +1415,14 @@ func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt { } } +// WithCMPUseManifestGeneratePaths enables or disables the use of the +// 'argocd.argoproj.io/manifest-generate-paths' annotation for manifest generation instead of transmit the whole repository. +func WithCMPUseManifestGeneratePaths(enabled bool) GenerateManifestOpt { + return func(o *generateManifestOpt) { + o.cmpUseManifestGeneratePaths = enabled + } +} + // GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource. func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, gitRepoPaths io.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { opt := newGenerateManifestOpt(opts...) @@ -1447,7 +1464,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, pluginName = q.ApplicationSource.Plugin.Name } // if pluginName is provided it has to be `-` or just `` if plugin version is empty - targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs) + targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, q.Repo.GetGitCreds(gitCredsStore), opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs, opt.cmpUseManifestGeneratePaths) if err != nil { err = fmt.Errorf("plugin sidecar failed. %s", err.Error()) } @@ -1490,7 +1507,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, for _, target := range targets { if q.AppLabelKey != "" && q.AppName != "" && !kube.IsCRD(target) { - err = resourceTracking.SetAppInstance(target, q.AppLabelKey, q.AppName, q.Namespace, v1alpha1.TrackingMethod(q.TrackingMethod)) + err = resourceTracking.SetAppInstance(target, q.AppLabelKey, q.AppName, q.Namespace, v1alpha1.TrackingMethod(q.TrackingMethod), q.InstallationID) if err != nil { return nil, fmt.Errorf("failed to set app instance tracking info on manifest: %w", err) } @@ -1964,7 +1981,7 @@ func getPluginParamEnvs(envVars []string, plugin *v1alpha1.ApplicationSourcePlug return env, nil } -func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) { +func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, creds git.Creds, tarDoneCh chan<- bool, tarExcludedGlobs []string, useManifestGeneratePaths bool) ([]*unstructured.Unstructured, error) { // compute variables. env, err := getPluginEnvs(envVars, q) if err != nil { @@ -1978,8 +1995,31 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p } defer io.Close(conn) + rootPath := repoPath + if useManifestGeneratePaths { + // Transmit the files under the common root path for all paths related to the manifest generate paths annotation. + rootPath = getApplicationRootPath(q, appPath, repoPath) + log.Debugf("common root path calculated for application %s: %s", q.AppName, rootPath) + } + + pluginConfigResponse, err := cmpClient.CheckPluginConfiguration(ctx, &emptypb.Empty{}) + if err != nil { + return nil, fmt.Errorf("error calling cmp-server checkPluginConfiguration: %w", err) + } + + if pluginConfigResponse.ProvideGitCreds { + if creds != nil { + closer, environ, err := creds.Environ() + if err != nil { + return nil, fmt.Errorf("failed to retrieve git creds environment variables: %w", err) + } + defer func() { _ = closer.Close() }() + env = append(env, environ...) + } + } + // generate manifests using commands provided in plugin config file in detected cmp-server sidecar - cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh, tarExcludedGlobs) + cmpManifests, err := generateManifestsCMP(ctx, appPath, rootPath, env, cmpClient, tarDoneCh, tarExcludedGlobs) if err != nil { return nil, fmt.Errorf("error generating manifests in cmp: %w", err) } @@ -2002,7 +2042,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p // generateManifestsCMP will send the appPath files to the cmp-server over a gRPC stream. // The cmp-server will generate the manifests. Returns a response object with the generated // manifests. -func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) { +func generateManifestsCMP(ctx context.Context, appPath, rootPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) { generateManifestStream, err := cmpClient.GenerateManifest(ctx, grpc_retry.Disable()) if err != nil { return nil, fmt.Errorf("error getting generateManifestStream: %w", err) @@ -2011,7 +2051,7 @@ func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []s cmp.WithTarDoneChan(tarDoneCh), } - err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, tarExcludedGlobs, opts...) + err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, rootPath, generateManifestStream, env, tarExcludedGlobs, opts...) if err != nil { return nil, fmt.Errorf("error sending file to cmp-server: %w", err) } @@ -2492,7 +2532,7 @@ func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bo } } - err = gitClient.Checkout(revision, submoduleEnabled) + _, err = gitClient.Checkout(revision, submoduleEnabled) if err != nil { // When fetching with no revision, only refs/heads/* and refs/remotes/origin/* are fetched. If checkout fails // for the given revision, try explicitly fetching it. @@ -2504,7 +2544,7 @@ func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bo return status.Errorf(codes.Internal, "Failed to checkout revision %s: %v", revision, err) } - err = gitClient.Checkout("FETCH_HEAD", submoduleEnabled) + _, err = gitClient.Checkout("FETCH_HEAD", submoduleEnabled) if err != nil { return status.Errorf(codes.Internal, "Failed to checkout FETCH_HEAD: %v", err) } @@ -2864,7 +2904,7 @@ func (s *Service) updateCachedRevision(logCtx *log.Entry, oldRev string, newRev } } - err := s.cache.SetNewRevisionManifests(newRev, oldRev, request.ApplicationSource, request.RefSources, request, request.Namespace, request.TrackingMethod, request.AppLabelKey, request.AppName, repoRefs) + err := s.cache.SetNewRevisionManifests(newRev, oldRev, request.ApplicationSource, request.RefSources, request, request.Namespace, request.TrackingMethod, request.AppLabelKey, request.AppName, repoRefs, request.InstallationID) if err != nil { if errors.Is(err, cache.ErrCacheMiss) { logCtx.Debugf("manifest cache miss during comparison for application %s in repo %s from revision %s", request.AppName, request.GetRepo().Repo, oldRev) diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 12f27a3f421f3..784ef0cafa12b 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -38,6 +38,10 @@ message ManifestRequest { repeated string projectSourceRepos = 24; // This is used to surface "source not permitted" errors for Helm repositories string projectName = 25; + // argocd.argoproj.io/manifest-generate-paths annotation value of the Application to allow optimize which resources propagated to cmpserver + string annotationManifestGeneratePaths = 26; + // Holds instance installation id + string installationID = 27; } message ManifestRequestWithFiles { @@ -281,9 +285,13 @@ message UpdateRevisionForPathsRequest { repeated string paths = 13; bool noRevisionCache = 14; + string installationID = 15; } message UpdateRevisionForPathsResponse { + // Changes indicates whether any changes were detected in the provided paths. If false, it means that the manifest + // cache was updated to the new revision. If true, it means that there are relevant changes in the repo files and + // that new manifests should be generated. bool changes = 1; string revision = 2; } diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 0c11553e5d7f4..d5f1061b3152c 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -100,6 +100,7 @@ func newCacheMocksWithOpts(repoCacheExpiration, revisionCacheExpiration, revisio } func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *gitmocks.Client, *repoCacheMocks) { + t.Helper() root, err := filepath.Abs(root) if err != nil { panic(err) @@ -108,7 +109,7 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, 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) @@ -140,6 +141,7 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git } func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *gitmocks.Client, *repoCacheMocks) { + t.Helper() helmClient := &helmmocks.Client{} gitClient := &gitmocks.Client{} paths := &iomocks.TempPaths{} @@ -162,16 +164,19 @@ func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *git } func newService(t *testing.T, root string) *Service { + t.Helper() service, _, _ := newServiceWithMocks(t, root, false) return service } func newServiceWithSignature(t *testing.T, root string) *Service { + t.Helper() service, _, _ := newServiceWithMocks(t, root, true) return service } func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { + t.Helper() var revisionErr error commitSHARegex := regexp.MustCompile("^[0-9A-Fa-f]{40}$") @@ -183,7 +188,7 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, 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) @@ -280,7 +285,7 @@ func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) { res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.Error(t, err) assert.NotContains(t, err.Error(), mustNotContain) - assert.Contains(t, err.Error(), "illegal filepath") + require.ErrorContains(t, err, "illegal filepath") assert.Nil(t, res) }) } @@ -313,7 +318,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}, Revision: mock.Anything} - err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil) + err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil, "") require.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) @@ -338,7 +343,7 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { ProjectSourceRepos: []string{"*"}, } - err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}, nil) + err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}, nil, "") require.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) @@ -684,8 +689,7 @@ func TestInvalidMetadata(t *testing.T) { src := argoappv1.ApplicationSource{Path: "./testdata/invalid-metadata", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "invalid-metadata", TrackingMethod: "annotation+label"} _, err := service.GenerateManifest(context.Background(), &q) - require.Error(t, err) - assert.Contains(t, err.Error(), "contains non-string value in the map under key \"invalid\"") + assert.ErrorContains(t, err, "contains non-string value in the map under key \"invalid\"") } func TestNilMetadataAccessors(t *testing.T) { @@ -763,8 +767,7 @@ func TestGenerateJsonnetLibOutside(t *testing.T) { ProjectSourceRepos: []string{"*"}, } _, err := service.GenerateManifest(context.Background(), &q) - require.Error(t, err) - require.Contains(t, err.Error(), "file '../../../testdata/jsonnet/vendor' resolved to outside repository root") + require.ErrorContains(t, err, "file '../../../testdata/jsonnet/vendor' resolved to outside repository root") } func TestManifestGenErrorCacheByNumRequests(t *testing.T) { @@ -774,7 +777,7 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { assert.NotNil(t, manifestRequest) cachedManifestResponse := &cache.CachedManifestResponse{} - err := service.cache.GetManifests(mock.Anything, manifestRequest.ApplicationSource, manifestRequest.RefSources, manifestRequest, manifestRequest.Namespace, "", manifestRequest.AppLabelKey, manifestRequest.AppName, cachedManifestResponse, nil) + err := service.cache.GetManifests(mock.Anything, manifestRequest.ApplicationSource, manifestRequest.RefSources, manifestRequest, manifestRequest.Namespace, "", manifestRequest.AppLabelKey, manifestRequest.AppName, cachedManifestResponse, nil, "") require.NoError(t, err) return cachedManifestResponse } @@ -1141,8 +1144,7 @@ func TestHelmWithMissingValueFiles(t *testing.T) { // Should fail since we're passing a non-existent values file, and error should indicate that _, err := service.GenerateManifest(context.Background(), req) - require.Error(t, err) - assert.Contains(t, err.Error(), fmt.Sprintf("%s: no such file or directory", missingValuesFile)) + require.ErrorContains(t, err, fmt.Sprintf("%s: no such file or directory", missingValuesFile)) // Should template without error even if defining a non-existent values file req.ApplicationSource.Helm.IgnoreMissingValueFiles = true @@ -1330,8 +1332,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + assert.ErrorContains(t, err, "outside repository root") }) t.Run("Values file with relative path pointing inside repo root", func(t *testing.T) { @@ -1385,8 +1386,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + assert.ErrorContains(t, err, "outside repository root") }) t.Run("Remote values file from forbidden protocol", func(t *testing.T) { @@ -1404,8 +1404,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - require.Error(t, err) - assert.Contains(t, err.Error(), "is not allowed") + assert.ErrorContains(t, err, "is not allowed") }) t.Run("Remote values file from custom allowed protocol", func(t *testing.T) { @@ -1423,8 +1422,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - require.Error(t, err) - assert.Contains(t, err.Error(), "s3://my-bucket/my-chart-values.yaml: no such file or directory") + assert.ErrorContains(t, err, "s3://my-bucket/my-chart-values.yaml: no such file or directory") }) } @@ -1589,6 +1587,7 @@ func TestListApps(t *testing.T) { "helm-with-dependencies-alias": "Helm", "helm-with-local-dependency": "Helm", "simple-chart": "Helm", + "broken-schema-verification": "Helm", } assert.Equal(t, expectedApps, res.Apps) } @@ -1849,6 +1848,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("No app name set and app specific file exists", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { + t.Helper() details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1862,6 +1862,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("No app specific override", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { + t.Helper() details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1876,6 +1877,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("Only app specific override", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + t.Helper() details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1890,6 +1892,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("App specific override", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { + t.Helper() details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1904,6 +1907,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("App specific overrides containing non-mergeable field", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { + t.Helper() details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1918,6 +1922,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("Broken app-specific overrides", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { + t.Helper() _, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, Source: &argoappv1.ApplicationSource{ @@ -1950,6 +1955,7 @@ func mkTempParameters(source string) string { // Simple wrapper run a test with a temporary copy of the testdata, because // the test would modify the data when run. func runWithTempTestdata(t *testing.T, path string, runner func(t *testing.T, path string)) { + t.Helper() tempDir := mkTempParameters("./testdata/app-parameters") runner(t, filepath.Join(tempDir, "app-parameters", path)) os.RemoveAll(tempDir) @@ -1958,6 +1964,7 @@ func runWithTempTestdata(t *testing.T, path string, runner func(t *testing.T, pa func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override", func(t *testing.T) { runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { + t.Helper() service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1987,6 +1994,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override Helm", func(t *testing.T) { runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) { + t.Helper() service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -2017,6 +2025,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Application specific override", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + t.Helper() manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -2047,6 +2056,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Multi-source with source as ref only does not generate manifests", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + t.Helper() manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -2068,6 +2078,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Application specific override for other app", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + t.Helper() manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -2098,6 +2109,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Override info does not appear in cache key", func(t *testing.T) { service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { + t.Helper() source := &argoappv1.ApplicationSource{ Path: path, } @@ -2114,7 +2126,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { // Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be // part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo // operations is the point of the cache. - err = service.cache.GetManifests(mock.Anything, source, argoappv1.RefTargetRevisionMapping{}, &argoappv1.ClusterInfo{}, "", "", "", "test", res, nil) + err = service.cache.GetManifests(mock.Anything, source, argoappv1.RefTargetRevisionMapping{}, &argoappv1.ClusterInfo{}, "", "", "", "test", res, nil, "") require.NoError(t, err) }) }) @@ -2378,6 +2390,7 @@ func TestFindManifests_Exclude_NothingMatches(t *testing.T) { } func tempDir(t *testing.T) string { + t.Helper() dir, err := os.MkdirTemp(".", "") require.NoError(t, err) t.Cleanup(func() { @@ -2392,6 +2405,7 @@ func tempDir(t *testing.T) string { } func walkFor(t *testing.T, root string, testPath string, run func(info fs.FileInfo)) { + t.Helper() hitExpectedPath := false err := filepath.Walk(root, func(path string, info fs.FileInfo, err error) error { if path == testPath { @@ -2857,8 +2871,7 @@ func TestTestRepoOCI(t *testing.T) { EnableOCI: true, }, }) - require.Error(t, err) - assert.Contains(t, err.Error(), "OCI Helm repository URL should include hostname and port only") + assert.ErrorContains(t, err, "OCI Helm repository URL should include hostname and port only") } func Test_getHelmDependencyRepos(t *testing.T) { @@ -2940,6 +2953,7 @@ func TestDirectoryPermissionInitializer(t *testing.T) { } func addHelmToGitRepo(t *testing.T, options newGitRepoOptions) { + t.Helper() err := os.WriteFile(filepath.Join(options.path, "Chart.yaml"), []byte("name: test\nversion: v1.0.0"), 0o777) require.NoError(t, err) for valuesFileName, values := range options.helmChartOptions.valuesFiles { @@ -2958,6 +2972,7 @@ func addHelmToGitRepo(t *testing.T, options newGitRepoOptions) { } func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { + t.Helper() if options.createPath { require.NoError(t, os.Mkdir(options.path, 0o755)) } @@ -3056,7 +3071,7 @@ func TestCheckoutRevisionPresentSkipFetch(t *testing.T) { gitClient := &gitmocks.Client{} gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", revision).Return(true) - gitClient.On("Checkout", revision, mock.Anything).Return(nil) + gitClient.On("Checkout", revision, mock.Anything).Return("", nil) err := checkoutRevision(gitClient, revision, false) require.NoError(t, err) @@ -3069,7 +3084,7 @@ func TestCheckoutRevisionNotPresentCallFetch(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", revision).Return(false) gitClient.On("Fetch", "").Return(nil) - gitClient.On("Checkout", revision, mock.Anything).Return(nil) + gitClient.On("Checkout", revision, mock.Anything).Return("", nil) err := checkoutRevision(gitClient, revision, false) require.NoError(t, err) @@ -3078,6 +3093,7 @@ func TestCheckoutRevisionNotPresentCallFetch(t *testing.T) { // runGit runs a git command in the given working directory. If the command succeeds, it returns the combined standard // and error output. If it fails, it stops the test with a failure message. func runGit(t *testing.T, workDir string, args ...string) string { + t.Helper() cmd := exec.Command("git", args...) cmd.Dir = workDir out, err := cmd.CombinedOutput() @@ -3394,7 +3410,7 @@ func TestErrorGetGitDirectories(t *testing.T) { }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3411,7 +3427,7 @@ func TestErrorGetGitDirectories(t *testing.T) { }, want: nil, wantErr: assert.Error}, {name: "ErrorVerifyCommit", fields: fields{service: func() *Service { s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("VerifyCommitSignature", mock.Anything).Return("", fmt.Errorf("revision %s is not signed", "sadfsadf")) gitClient.On("Root").Return(root) @@ -3448,7 +3464,7 @@ func TestGetGitDirectories(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return("", nil) gitClient.On("LsRemote", "HEAD").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(root, nil) @@ -3481,7 +3497,7 @@ func TestGetGitDirectoriesWithHiddenDirSupported(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return("", nil) gitClient.On("LsRemote", "HEAD").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(root, nil) @@ -3536,7 +3552,7 @@ func TestErrorGetGitFiles(t *testing.T) { }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3575,7 +3591,7 @@ func TestGetGitFiles(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return("", nil) gitClient.On("LsRemote", "HEAD").Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("Root").Return(root) gitClient.On("LsFiles", mock.Anything, mock.Anything).Once().Return(files, nil) @@ -3639,7 +3655,7 @@ func TestErrorUpdateRevisionForPaths(t *testing.T) { }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3657,7 +3673,7 @@ func TestErrorUpdateRevisionForPaths(t *testing.T) { }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveSyncedRevision", fields: fields{service: func() *Service { s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) gitClient.On("Root").Return(root) @@ -3710,7 +3726,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { }{ {name: "NoPathAbort", fields: func() fields { s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) }, ".") return fields{ service: s, @@ -3725,7 +3741,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError}, {name: "SameResolvedRevisionAbort", fields: func() fields { s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", "SYNCEDHEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3751,7 +3767,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", "SYNCEDHEAD").Once().Return("1e67a504d03def3a6a1125d934cb511680f72555", nil) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3780,7 +3796,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", "SYNCEDHEAD").Once().Return("1e67a504d03def3a6a1125d934cb511680f72555", nil) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3818,7 +3834,7 @@ func TestUpdateRevisionForPaths(t *testing.T) { gitClient.On("Init").Return(nil) gitClient.On("IsRevisionPresent", mock.Anything).Return(false) gitClient.On("Fetch", mock.Anything).Return(nil) - gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) + gitClient.On("Checkout", mock.Anything, mock.Anything).Return("", nil) gitClient.On("LsRemote", "HEAD").Once().Return("632039659e542ed7de0c170a4fcc1c571b288fc0", nil) gitClient.On("LsRemote", "SYNCEDHEAD").Once().Return("1e67a504d03def3a6a1125d934cb511680f72555", nil) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -4163,8 +4179,9 @@ func Test_GenerateManifests_Commands(t *testing.T) { Value: "false", }, }, - PassCredentials: true, - SkipCrds: true, + PassCredentials: true, + SkipCrds: true, + SkipSchemaValidation: false, ValueFiles: []string{ "my-chart-values.yaml", }, @@ -4310,3 +4327,43 @@ images: }, res.Commands) }) } + +func Test_SkipSchemaValidation(t *testing.T) { + t.Run("helm", func(t *testing.T) { + service := newService(t, "testdata/broken-schema-verification") + + q := apiclient.ManifestRequest{ + AppName: "test-app", + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: ".", + Helm: &argoappv1.ApplicationSourceHelm{ + SkipSchemaValidation: true, + }, + }, + } + + res, err := service.GenerateManifest(context.Background(), &q) + + require.NoError(t, err) + assert.Equal(t, []string{"helm template . --name-template test-app --include-crds --skip-schema-validation"}, res.Commands) + }) + t.Run("helm", func(t *testing.T) { + service := newService(t, "testdata/broken-schema-verification") + + q := apiclient.ManifestRequest{ + AppName: "test-app", + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: ".", + Helm: &argoappv1.ApplicationSourceHelm{ + SkipSchemaValidation: false, + }, + }, + } + + _, err := service.GenerateManifest(context.Background(), &q) + + require.ErrorContains(t, err, "values don't meet the specifications of the schema(s)") + }) +} diff --git a/reposerver/repository/testdata/broken-schema-verification/Chart.yaml b/reposerver/repository/testdata/broken-schema-verification/Chart.yaml new file mode 100644 index 0000000000000..27808fc463690 --- /dev/null +++ b/reposerver/repository/testdata/broken-schema-verification/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: broken-schema-verification +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/reposerver/repository/testdata/broken-schema-verification/templates/configmap.yaml b/reposerver/repository/testdata/broken-schema-verification/templates/configmap.yaml new file mode 100644 index 0000000000000..b3763e3f0752e --- /dev/null +++ b/reposerver/repository/testdata/broken-schema-verification/templates/configmap.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.name }} +data: {} \ No newline at end of file diff --git a/reposerver/repository/testdata/broken-schema-verification/values.schema.json b/reposerver/repository/testdata/broken-schema-verification/values.schema.json new file mode 100644 index 0000000000000..68277097d7ca9 --- /dev/null +++ b/reposerver/repository/testdata/broken-schema-verification/values.schema.json @@ -0,0 +1,18 @@ +{ + "$defs": { + "myType": { + "$ref": "http://doesnotexist.example.com/", + "title": "myType", + "type": "object" + } + }, + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "$ref": "#/$defs/myType" + } + } +} \ No newline at end of file diff --git a/reposerver/repository/testdata/broken-schema-verification/values.yaml b/reposerver/repository/testdata/broken-schema-verification/values.yaml new file mode 100644 index 0000000000000..e0320b52f196d --- /dev/null +++ b/reposerver/repository/testdata/broken-schema-verification/values.yaml @@ -0,0 +1 @@ +name: test-configmap \ No newline at end of file diff --git a/reposerver/repository/utils.go b/reposerver/repository/utils.go new file mode 100644 index 0000000000000..d77bef728d92a --- /dev/null +++ b/reposerver/repository/utils.go @@ -0,0 +1,85 @@ +package repository + +import ( + "path/filepath" + "strings" + + securejoin "github.com/cyphar/filepath-securejoin" + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io/files" +) + +// getApplicationRootPath returns the common root path (shortest shared structure between all paths) among a +// set of application-related paths for manifest generation. AppPath is the lower possible value +func getApplicationRootPath(q *apiclient.ManifestRequest, appPath, repoPath string) string { + paths := getPaths(q, appPath, repoPath) + + if len(paths) == 0 { + // backward compatibility, by default the root path is the repoPath + return repoPath + } + + // the app path must be the lower possible value + commonParts := strings.Split(appPath, string(filepath.Separator)) + + var disjoint bool + for _, path := range paths { + parts := strings.Split(path, string(filepath.Separator)) + // find the minimum length between the current common parts and the current path + minLen := func(a, b int) int { + if a < b { + return a + } + return b + }(len(commonParts), len(parts)) + + // check if diverge /disjoint in some point + for i := 0; i < minLen; i++ { + if commonParts[i] != parts[i] { + commonParts = commonParts[:i] + disjoint = true + break + } + } + + // for non-disjoint paths + if !disjoint && minLen < len(commonParts) { + commonParts = commonParts[:minLen] + } + } + return string(filepath.Separator) + filepath.Join(commonParts...) +} + +// getPaths retrieves all absolute paths associated with the generation of application manifests. +func getPaths(q *apiclient.ManifestRequest, appPath, repoPath string) []string { + var paths []string + for _, annotationPath := range strings.Split(q.AnnotationManifestGeneratePaths, ";") { + if annotationPath == "" { + continue + } + var err error + var path, unsafePath string + + if filepath.IsAbs(annotationPath) { + unsafePath = filepath.Clean(annotationPath) + } else { + appRelPath, err := files.RelativePath(appPath, repoPath) + if err != nil { + log.Errorf("error building app relative path: %v", err) + continue + } + unsafePath = filepath.Clean(filepath.Join(appRelPath, annotationPath)) + } + + path, err = securejoin.SecureJoin(repoPath, unsafePath) + if err != nil { + log.Errorf("error joining repoPath %q and absolute unsafePath %q: %v", repoPath, unsafePath, err) + continue + } + + paths = append(paths, path) + } + return paths +} diff --git a/reposerver/repository/utils_test.go b/reposerver/repository/utils_test.go new file mode 100644 index 0000000000000..3eb2428f09c03 --- /dev/null +++ b/reposerver/repository/utils_test.go @@ -0,0 +1,46 @@ +package repository + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" +) + +func TestGetCommonRootPath(t *testing.T) { + t.Parallel() + + repoRoot := "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731" + + tests := []struct { + name string + annotation string + appPath string + expectedRootPath string + }{ + {"app path", ".", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld"}, + {"app path and relative", "../../overlays;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", repoRoot}, + {"app path and absolute path", "/services;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"several relative paths", "../../;..;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + // backward compatibility test + {"no annotation", "", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", repoRoot}, + // appPath should be the lower calculated root path + {"relative subdir", "./manifests", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld"}, + // glob pattern + {"glob", "/services/shared/*-secret.yaml", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"relative glob", "../*", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"duplicate slashes", "//services/shared/*-secret.yaml", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + req := &apiclient.ManifestRequest{AnnotationManifestGeneratePaths: tt.annotation} + rootPath := getApplicationRootPath(req, tt.appPath, repoRoot) + assert.Equal(t, tt.expectedRootPath, rootPath, "input and output should match") + }) + } +} diff --git a/resource_customizations/acid.zalan.do/postgresql/health.lua b/resource_customizations/acid.zalan.do/postgresql/health.lua new file mode 100644 index 0000000000000..75bb8a15855c2 --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/health.lua @@ -0,0 +1,30 @@ +-- Waiting for status info => Progressing +if obj.status == nil or obj.status.PostgresClusterStatus == nil then + return { + status = "Progressing", + message = "Waiting for postgres cluster status...", + } +end + +-- Running => Healthy +if obj.status.PostgresClusterStatus == "Running" then + return { + status = "Healthy", + message = obj.status.PostgresClusterStatus, + } +end + +-- Creating/Updating => Progressing +if obj.status.PostgresClusterStatus == "Creating" or obj.status.PostgresClusterStatus == "Updating" then + return { + status = "Progressing", + message = obj.status.PostgresClusterStatus, + } +end + +-- CreateFailed/UpdateFailed/SyncFailed/Invalid/etc => Degraded +-- See https://github.com/zalando/postgres-operator/blob/0745ce7c/pkg/apis/acid.zalan.do/v1/const.go#L4-L13 +return { + status = "Degraded", + message = obj.status.PostgresClusterStatus, +} \ No newline at end of file diff --git a/resource_customizations/acid.zalan.do/postgresql/health_test.yaml b/resource_customizations/acid.zalan.do/postgresql/health_test.yaml new file mode 100644 index 0000000000000..67c9e4d2263ce --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for postgres cluster status..." + inputPath: testdata/provisioning.yaml +- healthStatus: + status: Progressing + message: "Updating" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Running" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "UpdateFailed" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/acid.zalan.do/postgresql/testdata/degraded.yaml b/resource_customizations/acid.zalan.do/postgresql/testdata/degraded.yaml new file mode 100644 index 0000000000000..c17f3383c0e30 --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/testdata/degraded.yaml @@ -0,0 +1,27 @@ +apiVersion: acid.zalan.do/v1 +kind: postgresql +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-db:acid.zalan.do/postgresql:foo/foobar-db + creationTimestamp: '2024-10-07T09:06:07Z' + generation: 4 + name: foobar-db + namespace: foo + resourceVersion: '242244' + uid: 741b63d5-8deb-45ef-af80-09d558d355a7 +spec: + databases: + foobar: root + enableLogicalBackup: false + numberOfInstances: 1 + postgresql: + parameters: + password_encryption: scram-sha-256 + version: '15' + teamId: foobar + users: {} + volume: + size: 1Gi +status: + PostgresClusterStatus: UpdateFailed diff --git a/resource_customizations/acid.zalan.do/postgresql/testdata/healthy.yaml b/resource_customizations/acid.zalan.do/postgresql/testdata/healthy.yaml new file mode 100644 index 0000000000000..756352dedd259 --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/testdata/healthy.yaml @@ -0,0 +1,27 @@ +apiVersion: acid.zalan.do/v1 +kind: postgresql +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-db:acid.zalan.do/postgresql:foo/foobar-db + creationTimestamp: '2024-10-07T09:06:07Z' + generation: 4 + name: foobar-db + namespace: foo + resourceVersion: '242244' + uid: 741b63d5-8deb-45ef-af80-09d558d355a7 +spec: + databases: + foobar: root + enableLogicalBackup: false + numberOfInstances: 1 + postgresql: + parameters: + password_encryption: scram-sha-256 + version: '15' + teamId: foobar + users: {} + volume: + size: 1Gi +status: + PostgresClusterStatus: Running diff --git a/resource_customizations/acid.zalan.do/postgresql/testdata/progressing.yaml b/resource_customizations/acid.zalan.do/postgresql/testdata/progressing.yaml new file mode 100644 index 0000000000000..a1e77c7964e7e --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/testdata/progressing.yaml @@ -0,0 +1,27 @@ +apiVersion: acid.zalan.do/v1 +kind: postgresql +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-db:acid.zalan.do/postgresql:foo/foobar-db + creationTimestamp: '2024-10-07T09:06:07Z' + generation: 4 + name: foobar-db + namespace: foo + resourceVersion: '242244' + uid: 741b63d5-8deb-45ef-af80-09d558d355a7 +spec: + databases: + foobar: root + enableLogicalBackup: false + numberOfInstances: 1 + postgresql: + parameters: + password_encryption: scram-sha-256 + version: '15' + teamId: foobar + users: {} + volume: + size: 1Gi +status: + PostgresClusterStatus: Updating diff --git a/resource_customizations/acid.zalan.do/postgresql/testdata/provisioning.yaml b/resource_customizations/acid.zalan.do/postgresql/testdata/provisioning.yaml new file mode 100644 index 0000000000000..73f0097d6afa5 --- /dev/null +++ b/resource_customizations/acid.zalan.do/postgresql/testdata/provisioning.yaml @@ -0,0 +1,21 @@ +apiVersion: acid.zalan.do/v1 +kind: postgresql +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-db:acid.zalan.do/postgresql:foo/foobar-db + name: foobar-db + namespace: foo +spec: + databases: + foobar: root + enableLogicalBackup: false + numberOfInstances: 1 + postgresql: + parameters: + password_encryption: scram-sha-256 + version: '15' + teamId: foobar + users: {} + volume: + size: 1Gi \ No newline at end of file diff --git a/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health.lua b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health.lua new file mode 100644 index 0000000000000..9cc7edc368b33 --- /dev/null +++ b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health.lua @@ -0,0 +1,31 @@ +function getStatus(obj) + local hs = {} + hs.status = "Progressing" + hs.message = "Initializing cluster resource set" + + if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + + -- Ready + if condition.type == "ResourcesApplied" and condition.status == "True" then + hs.status = "Healthy" + hs.message = "cluster resource set is applied" + return hs + end + + -- Resources Applied + if condition.type == "ResourcesApplied" and condition.status == "False" then + hs.status = "Degraded" + hs.message = condition.message + return hs + end + + end + end + end + return hs +end + +local hs = getStatus(obj) +return hs \ No newline at end of file diff --git a/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health_test.yaml b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health_test.yaml new file mode 100644 index 0000000000000..373d143f9bc26 --- /dev/null +++ b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: 'Initializing cluster resource set' + inputPath: testdata/progressing_resourceapplied.yaml +- healthStatus: + status: Degraded + message: 'Failed to apply resources' + inputPath: testdata/degraded_resourceapplied.yaml +- healthStatus: + status: Healthy + message: 'cluster resource set is applied' + inputPath: testdata/healthy_resourceapplied.yaml \ No newline at end of file diff --git a/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/degraded_resourceapplied.yaml b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/degraded_resourceapplied.yaml new file mode 100644 index 0000000000000..ec27b67ed4be5 --- /dev/null +++ b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/degraded_resourceapplied.yaml @@ -0,0 +1,27 @@ +apiVersion: addons.cluster.x-k8s.io/v1beta1 +kind: ClusterResourceSet +metadata: + finalizers: + - addons.cluster.x-k8s.io + generation: 1 + labels: + app.argocd.io/instance: clustername + name: clustername-resource-set + namespace: capi-managed-cluster +spec: + clusterSelector: + matchLabels: + clusterName: clustername + resources: + - kind: ConfigMap + name: clustername-default-rbac + strategy: ApplyOnce +status: + conditions: + - lastTransitionTime: '2024-11-11T03:28:48Z' + message: "Failed to apply resources" + reason: RemoteClusterClientFailed + severity: Error + status: 'False' + type: ResourcesApplied + observedGeneration: 1 diff --git a/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/healthy_resourceapplied.yaml b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/healthy_resourceapplied.yaml new file mode 100644 index 0000000000000..4aaf8c7b36104 --- /dev/null +++ b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/healthy_resourceapplied.yaml @@ -0,0 +1,24 @@ +apiVersion: addons.cluster.x-k8s.io/v1beta1 +kind: ClusterResourceSet +metadata: + finalizers: + - addons.cluster.x-k8s.io + generation: 2 + labels: + app.argocd.io/instance: clustername + name: clustername-resource-set + namespace: capi-managed-cluster +spec: + clusterSelector: + matchLabels: + clusterName: clustername + resources: + - kind: ConfigMap + name: clustername-default-rbac + strategy: ApplyOnce +status: + conditions: + - lastTransitionTime: '2024-11-08T08:49:13Z' + status: 'True' + type: ResourcesApplied + observedGeneration: 2 diff --git a/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/progressing_resourceapplied.yaml b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/progressing_resourceapplied.yaml new file mode 100644 index 0000000000000..f6e499abbc8a6 --- /dev/null +++ b/resource_customizations/addons.cluster.x-k8s.io/ClusterResourceSet/testdata/progressing_resourceapplied.yaml @@ -0,0 +1,18 @@ +apiVersion: addons.cluster.x-k8s.io/v1beta1 +kind: ClusterResourceSet +metadata: + finalizers: + - addons.cluster.x-k8s.io + generation: 2 + labels: + app.argocd.io/instance: clustername + name: clustername-resource-set + namespace: capi-managed-cluster +spec: + clusterSelector: + matchLabels: + clusterName: clustername + resources: + - kind: ConfigMap + name: clustername-default-rbac + strategy: ApplyOnce diff --git a/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml b/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml index f3c3057dc88be..194794efec449 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml +++ b/resource_customizations/argoproj.io/Rollout/actions/action_test.yaml @@ -5,6 +5,7 @@ discoveryTests: disabled: false - name: restart disabled: false + displayName: Restart Pods - name: abort disabled: false - name: retry @@ -15,6 +16,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -27,6 +29,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -39,6 +42,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: false - name: abort @@ -51,6 +55,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -63,6 +68,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -75,6 +81,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -87,6 +94,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort @@ -99,6 +107,7 @@ discoveryTests: result: - name: restart disabled: false + displayName: Restart Pods - name: resume disabled: true - name: abort diff --git a/resource_customizations/argoproj.io/Rollout/actions/discovery.lua b/resource_customizations/argoproj.io/Rollout/actions/discovery.lua index 86a5307e0023b..966034d369b37 100644 --- a/resource_customizations/argoproj.io/Rollout/actions/discovery.lua +++ b/resource_customizations/argoproj.io/Rollout/actions/discovery.lua @@ -1,5 +1,8 @@ local actions = {} -actions["restart"] = {["disabled"] = false} +actions["restart"] = { + ["disabled"] = false, + ["displayName"] = "Restart Pods" +} local paused = false if obj.status ~= nil and obj.status.pauseConditions ~= nil then diff --git a/resource_customizations/grafana.integreatly.org/Grafana/health.lua b/resource_customizations/grafana.integreatly.org/Grafana/health.lua new file mode 100644 index 0000000000000..250034a120aab --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/health.lua @@ -0,0 +1,30 @@ + +-- if no status info available yet, assume progressing +if obj.status == nil or obj.status.stageStatus == nil then + return { + status = "Progressing", + message = "Waiting for Grafana status info", + } +end + +-- if last stage failed, we are stuck here +if obj.status.stageStatus == "failed" then + return { + status = "Degraded", + message = "Failed at stage " .. obj.status.stage, + } +end + +-- only if "complete" stage was successful, Grafana can be considered healthy +if obj.status.stage == "complete" and obj.status.stageStatus == "success" then + return { + status = "Healthy", + message = "", + } +end + +-- no final status yet, assume progressing +return { + status = "Progressing", + message = obj.status.stage, +} \ No newline at end of file diff --git a/resource_customizations/grafana.integreatly.org/Grafana/health_test.yaml b/resource_customizations/grafana.integreatly.org/Grafana/health_test.yaml new file mode 100644 index 0000000000000..8c076a46b0b56 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for Grafana status info" + inputPath: testdata/provisioning.yaml +- healthStatus: + status: Progressing + message: "deployment" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "Failed at stage ingress" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/grafana.integreatly.org/Grafana/testdata/degraded.yaml b/resource_customizations/grafana.integreatly.org/Grafana/testdata/degraded.yaml new file mode 100644 index 0000000000000..0fadec094c2d8 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/testdata/degraded.yaml @@ -0,0 +1,47 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/Grafana:foo/grafana + creationTimestamp: '2024-10-07T08:46:00Z' + generation: 3 + labels: + dashboards: grafana + folders: grafana + name: grafana + namespace: foo + resourceVersion: '343511' + uid: d2f0496d-cd5c-46bf-8630-de827b6d59b0 +spec: + deployment: + metadata: {} + spec: + template: + metadata: {} + spec: + containers: + - image: docker.io/grafana/grafana:11.1.4 + name: grafana + volumeMounts: + - mountPath: /etc/ssl/certs/ca-certificates.crt + name: tls-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: tls-ca-bundle + secret: + items: + - key: tls-ca-bundle.pem + path: tls-ca-bundle.pem + secretName: tls-ca-bundle-secret + version: 10.4.3 +status: + adminUrl: http://grafana-service.foo:3000 + dashboards: + - foo/dashboard-argocd/qPkgGHg7k + datasources: + - foo/cluster-local/927b3c23-e25f-4cbe-a82f-effbb0bbbf40 + stage: ingress + stageStatus: failed + version: 11.1.4 diff --git a/resource_customizations/grafana.integreatly.org/Grafana/testdata/healthy.yaml b/resource_customizations/grafana.integreatly.org/Grafana/testdata/healthy.yaml new file mode 100644 index 0000000000000..b1b4832b9b967 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/testdata/healthy.yaml @@ -0,0 +1,47 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/Grafana:foo/grafana + creationTimestamp: '2024-10-07T08:46:00Z' + generation: 3 + labels: + dashboards: grafana + folders: grafana + name: grafana + namespace: foo + resourceVersion: '343511' + uid: d2f0496d-cd5c-46bf-8630-de827b6d59b0 +spec: + deployment: + metadata: {} + spec: + template: + metadata: {} + spec: + containers: + - image: docker.io/grafana/grafana:11.1.4 + name: grafana + volumeMounts: + - mountPath: /etc/ssl/certs/ca-certificates.crt + name: tls-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: tls-ca-bundle + secret: + items: + - key: tls-ca-bundle.pem + path: tls-ca-bundle.pem + secretName: tls-ca-bundle-secret + version: 10.4.3 +status: + adminUrl: http://grafana-service.foo:3000 + dashboards: + - foo/dashboard-argocd/qPkgGHg7k + datasources: + - foo/cluster-local/927b3c23-e25f-4cbe-a82f-effbb0bbbf40 + stage: complete + stageStatus: success + version: 11.1.4 diff --git a/resource_customizations/grafana.integreatly.org/Grafana/testdata/progressing.yaml b/resource_customizations/grafana.integreatly.org/Grafana/testdata/progressing.yaml new file mode 100644 index 0000000000000..2efa0a093f0b3 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/testdata/progressing.yaml @@ -0,0 +1,47 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/Grafana:foo/grafana + creationTimestamp: '2024-10-07T08:46:00Z' + generation: 3 + labels: + dashboards: grafana + folders: grafana + name: grafana + namespace: foo + resourceVersion: '343511' + uid: d2f0496d-cd5c-46bf-8630-de827b6d59b0 +spec: + deployment: + metadata: {} + spec: + template: + metadata: {} + spec: + containers: + - image: docker.io/grafana/grafana:11.1.4 + name: grafana + volumeMounts: + - mountPath: /etc/ssl/certs/ca-certificates.crt + name: tls-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: tls-ca-bundle + secret: + items: + - key: tls-ca-bundle.pem + path: tls-ca-bundle.pem + secretName: tls-ca-bundle-secret + version: 10.4.3 +status: + adminUrl: http://grafana-service.foo:3000 + dashboards: + - foo/dashboard-argocd/qPkgGHg7k + datasources: + - foo/cluster-local/927b3c23-e25f-4cbe-a82f-effbb0bbbf40 + stage: deployment + stageStatus: success + version: 11.1.4 diff --git a/resource_customizations/grafana.integreatly.org/Grafana/testdata/provisioning.yaml b/resource_customizations/grafana.integreatly.org/Grafana/testdata/provisioning.yaml new file mode 100644 index 0000000000000..cb71c49fe5360 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/Grafana/testdata/provisioning.yaml @@ -0,0 +1,39 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/Grafana:foo/grafana + creationTimestamp: '2024-10-07T08:46:00Z' + generation: 3 + labels: + dashboards: grafana + folders: grafana + name: grafana + namespace: foo + resourceVersion: '343511' + uid: d2f0496d-cd5c-46bf-8630-de827b6d59b0 +spec: + deployment: + metadata: {} + spec: + template: + metadata: {} + spec: + containers: + - image: docker.io/grafana/grafana:11.1.4 + name: grafana + volumeMounts: + - mountPath: /etc/ssl/certs/ca-certificates.crt + name: tls-ca-bundle + readOnly: true + subPath: tls-ca-bundle.pem + volumes: + - name: tls-ca-bundle + secret: + items: + - key: tls-ca-bundle.pem + path: tls-ca-bundle.pem + secretName: tls-ca-bundle-secret + version: 10.4.3 +status: \ No newline at end of file diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health.lua b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health.lua new file mode 100644 index 0000000000000..01433f95ad4c1 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health.lua @@ -0,0 +1,20 @@ + +-- if UID not yet created, we are progressing +if obj.status == nil or obj.status.uid == "" then + return { + status = "Progressing", + message = "", + } +end + +-- NoMatchingInstances distinguishes if we are healthy or degraded +if obj.status.NoMatchingInstances then + return { + status = "Degraded", + message = "can't find matching grafana instance", + } +end +return { + status = "Healthy", + message = "", +} \ No newline at end of file diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health_test.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health_test.yaml new file mode 100644 index 0000000000000..26427c2455f93 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "can't find matching grafana instance" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/degraded.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/degraded.yaml new file mode 100644 index 0000000000000..3c3559eba2a35 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/degraded.yaml @@ -0,0 +1,42 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: GrafanaDatasource +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/GrafanaDatasource:foo/cluster-local + creationTimestamp: '2024-10-07T09:37:21Z' + generation: 1 + name: cluster-local + namespace: foo + resourceVersion: '356565' + uid: 927b3c23-e25f-4cbe-a82f-effbb0bbbf40 +spec: + allowCrossNamespaceImport: true + datasource: + access: proxy + editable: true + isDefault: true + jsonData: + httpHeaderName1: Authorization + timeInterval: 5s + tlsSkipVerify: true + name: cluster-local + secureJsonData: + httpHeaderValue1: Bearer ${token} + type: prometheus + url: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 + instanceSelector: + matchLabels: + dashboards: invalid-selector + resyncPeriod: 5m + valuesFrom: + - targetPath: secureJsonData.httpHeaderValue1 + valueFrom: + secretKeyRef: + key: token + name: grafana-token +status: + NoMatchingInstances: true + hash: 56e40622b6a72563637b7c5f33c26d1ce87839dd5897a4a263fbd3d947f951cb + lastResync: '2024-10-09T10:30:40Z' + uid: 927b3c23-e25f-4cbe-a82f-effbb0bbbf40 diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/healthy.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/healthy.yaml new file mode 100644 index 0000000000000..6217c5eecb305 --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/healthy.yaml @@ -0,0 +1,41 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: GrafanaDatasource +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/GrafanaDatasource:foo/cluster-local + creationTimestamp: '2024-10-07T09:37:21Z' + generation: 1 + name: cluster-local + namespace: foo + resourceVersion: '356565' + uid: 927b3c23-e25f-4cbe-a82f-effbb0bbbf40 +spec: + allowCrossNamespaceImport: true + datasource: + access: proxy + editable: true + isDefault: true + jsonData: + httpHeaderName1: Authorization + timeInterval: 5s + tlsSkipVerify: true + name: cluster-local + secureJsonData: + httpHeaderValue1: Bearer ${token} + type: prometheus + url: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 + instanceSelector: + matchLabels: + dashboards: grafana + resyncPeriod: 5m + valuesFrom: + - targetPath: secureJsonData.httpHeaderValue1 + valueFrom: + secretKeyRef: + key: token + name: grafana-token +status: + hash: 56e40622b6a72563637b7c5f33c26d1ce87839dd5897a4a263fbd3d947f951cb + lastResync: '2024-10-09T10:30:40Z' + uid: 927b3c23-e25f-4cbe-a82f-effbb0bbbf40 diff --git a/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/progressing.yaml b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/progressing.yaml new file mode 100644 index 0000000000000..fef53aa72ef1b --- /dev/null +++ b/resource_customizations/grafana.integreatly.org/GrafanaDatasource/testdata/progressing.yaml @@ -0,0 +1,35 @@ +apiVersion: grafana.integreatly.org/v1beta1 +kind: GrafanaDatasource +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + argocd.argoproj.io/tracking-id: foobar-admin:grafana.integreatly.org/GrafanaDatasource:foo/cluster-local + name: cluster-local + namespace: foo +spec: + allowCrossNamespaceImport: true + datasource: + access: proxy + editable: true + isDefault: true + jsonData: + httpHeaderName1: Authorization + timeInterval: 5s + tlsSkipVerify: true + name: cluster-local + secureJsonData: + httpHeaderValue1: Bearer ${token} + type: prometheus + url: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 + instanceSelector: + matchLabels: + dashboards: grafana + resyncPeriod: 5m + valuesFrom: + - targetPath: secureJsonData.httpHeaderValue1 + valueFrom: + secretKeyRef: + key: token + name: grafana-token +status: + uid: "" diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/health.lua b/resource_customizations/k8s.keycloak.org/Keycloak/health.lua new file mode 100644 index 0000000000000..a82135af0a119 --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/health.lua @@ -0,0 +1,32 @@ +if obj.status == nil or obj.status.conditions == nil then + -- no status info available yet + return { + status = "Progressing", + message = "Waiting for Keycloak status conditions to exist", + } +end + +-- Sort conditions by lastTransitionTime, from old to new. +table.sort(obj.status.conditions, function(a, b) + return a.lastTransitionTime < b.lastTransitionTime +end) + +for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" and condition.status == "True" then + return { + status = "Healthy", + message = "", + } + elseif condition.type == "HasErrors" and condition.status == "True" then + return { + status = "Degraded", + message = "Has Errors: " .. condition.message, + } + end +end + +-- We couldn't find matching conditions yet, so assume progressing +return { + status = "Progressing", + message = "", +} \ No newline at end of file diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/health_test.yaml b/resource_customizations/k8s.keycloak.org/Keycloak/health_test.yaml new file mode 100644 index 0000000000000..8560f67890517 --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for Keycloak status conditions to exist" + inputPath: testdata/provisioning.yaml +- healthStatus: + status: Progressing + message: "" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "Has Errors: Waiting for foo/keycloak-1 due to CrashLoopBackOff: back-off 10s" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/testdata/degraded.yaml b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/degraded.yaml new file mode 100644 index 0000000000000..60c709a1ded1f --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/degraded.yaml @@ -0,0 +1,73 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: Keycloak +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + argocd.argoproj.io/tracking-id: foobar-keycloak:k8s.keycloak.org/Keycloak:foo/keycloak + creationTimestamp: '2024-10-07T09:06:33Z' + generation: 4 + name: keycloak + namespace: foo + resourceVersion: '343382' + uid: 4e08e59c-1b6b-4b13-8a1a-bbce3f91bd68 +spec: + db: + host: keycloak-db + passwordSecret: + key: password + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + usernameSecret: + key: username + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + vendor: postgres + hostname: + admin: https://keycloak.apps-crc.testing + hostname: keycloak.apps-crc.testing + http: + httpEnabled: false + tlsSecret: keycloak-tls + ingress: + enabled: false + instances: 2 + unsupported: + podTemplate: + spec: + containers: + - env: + - name: KC_HTTPS_TRUST_STORE_FILE + value: /truststore/openshiftca.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: OpenshiftCA + - name: KC_HTTPS_TRUST_STORE_TYPE + value: JKS + - name: KC_LOG_LEVEL + value: INFO + volumeMounts: + - mountPath: /truststore + name: truststore-volume + volumes: + - name: truststore-volume + secret: + secretName: keycloak-truststore +status: + conditions: + - lastTransitionTime: '2024-10-09T10:13:00.097073410Z' + message: Waiting for more replicas + observedGeneration: 5 + status: 'False' + type: Ready + - lastTransitionTime: '2024-10-09T10:14:12.070548569Z' + message: >- + Waiting for foo/keycloak-1 due to CrashLoopBackOff: back-off 10s + observedGeneration: 5 + status: 'True' + type: HasErrors + - lastTransitionTime: '2024-10-09T10:12:59.087234931Z' + message: Rolling out deployment update + observedGeneration: 5 + status: 'True' + type: RollingUpdate + instances: 1 + observedGeneration: 5 + selector: >- + app=keycloak,app.kubernetes.io/managed-by=keycloak-operator,app.kubernetes.io/instance=keycloak diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/testdata/healthy.yaml b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/healthy.yaml new file mode 100644 index 0000000000000..f04067cf71366 --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/healthy.yaml @@ -0,0 +1,77 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: Keycloak +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + argocd.argoproj.io/tracking-id: foobar-keycloak:k8s.keycloak.org/Keycloak:foo/keycloak + creationTimestamp: '2024-10-07T09:06:33Z' + generation: 4 + name: keycloak + namespace: foo + resourceVersion: '343382' + uid: 4e08e59c-1b6b-4b13-8a1a-bbce3f91bd68 +spec: + additionalOptions: + - name: proxy-headers + value: xforwarded + db: + host: keycloak-db + passwordSecret: + key: password + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + usernameSecret: + key: username + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + vendor: postgres + hostname: + admin: https://keycloak.apps-crc.testing + hostname: keycloak.apps-crc.testing + http: + httpEnabled: false + tlsSecret: keycloak-tls + ingress: + enabled: false + instances: 2 + unsupported: + podTemplate: + spec: + containers: + - env: + - name: KC_HTTPS_TRUST_STORE_FILE + value: /truststore/openshiftca.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: OpenshiftCA + - name: KC_HTTPS_TRUST_STORE_TYPE + value: JKS + - name: KC_LOG_LEVEL + value: INFO + volumeMounts: + - mountPath: /truststore + name: truststore-volume + volumes: + - name: truststore-volume + secret: + secretName: keycloak-truststore +status: + conditions: + - lastTransitionTime: '2024-10-09T09:55:28.695748046Z' + message: '' + observedGeneration: 4 + status: 'True' + type: Ready + - lastTransitionTime: '2024-10-08T11:11:08.814752530Z' + message: >- + warning: You need to specify these fields as the first-class citizen of + the CR: proxy-headers + observedGeneration: 4 + status: 'False' + type: HasErrors + - lastTransitionTime: '2024-10-09T09:47:33.600863636Z' + message: '' + observedGeneration: 4 + status: 'False' + type: RollingUpdate + instances: 2 + observedGeneration: 4 + selector: >- + app=keycloak,app.kubernetes.io/managed-by=keycloak-operator,app.kubernetes.io/instance=keycloak diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/testdata/progressing.yaml b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/progressing.yaml new file mode 100644 index 0000000000000..d66e46e5b00f6 --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/progressing.yaml @@ -0,0 +1,77 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: Keycloak +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + argocd.argoproj.io/tracking-id: foobar-keycloak:k8s.keycloak.org/Keycloak:foo/keycloak + creationTimestamp: '2024-10-07T09:06:33Z' + generation: 4 + name: keycloak + namespace: foo + resourceVersion: '343382' + uid: 4e08e59c-1b6b-4b13-8a1a-bbce3f91bd68 +spec: + additionalOptions: + - name: proxy-headers + value: xforwarded + db: + host: keycloak-db + passwordSecret: + key: password + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + usernameSecret: + key: username + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + vendor: postgres + hostname: + admin: https://keycloak.apps-crc.testing + hostname: keycloak.apps-crc.testing + http: + httpEnabled: false + tlsSecret: keycloak-tls + ingress: + enabled: false + instances: 2 + unsupported: + podTemplate: + spec: + containers: + - env: + - name: KC_HTTPS_TRUST_STORE_FILE + value: /truststore/openshiftca.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: OpenshiftCA + - name: KC_HTTPS_TRUST_STORE_TYPE + value: JKS + - name: KC_LOG_LEVEL + value: INFO + volumeMounts: + - mountPath: /truststore + name: truststore-volume + volumes: + - name: truststore-volume + secret: + secretName: keycloak-truststore +status: + conditions: + - lastTransitionTime: '2024-10-09T10:13:00.097073410Z' + message: Waiting for more replicas + observedGeneration: 5 + status: 'False' + type: Ready + - lastTransitionTime: '2024-10-08T11:11:08.814752530Z' + message: >- + warning: You need to specify these fields as the first-class citizen of + the CR: proxy-headers + observedGeneration: 5 + status: 'False' + type: HasErrors + - lastTransitionTime: '2024-10-09T10:12:59.087234931Z' + message: Rolling out deployment update + observedGeneration: 5 + status: 'True' + type: RollingUpdate + instances: 1 + observedGeneration: 5 + selector: >- + app=keycloak,app.kubernetes.io/managed-by=keycloak-operator,app.kubernetes.io/instance=keycloak diff --git a/resource_customizations/k8s.keycloak.org/Keycloak/testdata/provisioning.yaml b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/provisioning.yaml new file mode 100644 index 0000000000000..b28dbf31e81bd --- /dev/null +++ b/resource_customizations/k8s.keycloak.org/Keycloak/testdata/provisioning.yaml @@ -0,0 +1,52 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: Keycloak +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + argocd.argoproj.io/tracking-id: foobar-keycloak:k8s.keycloak.org/Keycloak:foo/keycloak + creationTimestamp: '2024-10-07T09:06:33Z' + generation: 4 + name: keycloak + namespace: foo + resourceVersion: '343382' + uid: 4e08e59c-1b6b-4b13-8a1a-bbce3f91bd68 +spec: + db: + host: keycloak-db + passwordSecret: + key: password + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + usernameSecret: + key: username + name: keycloak.keycloak-db.credentials.postgresql.acid.zalan.do + vendor: postgres + hostname: + admin: https://keycloak.apps-crc.testing + hostname: keycloak.apps-crc.testing + http: + httpEnabled: false + tlsSecret: keycloak-tls + ingress: + enabled: false + instances: 2 + unsupported: + podTemplate: + spec: + containers: + - env: + - name: KC_HTTPS_TRUST_STORE_FILE + value: /truststore/openshiftca.jks + - name: KC_HTTPS_TRUST_STORE_PASSWORD + value: OpenshiftCA + - name: KC_HTTPS_TRUST_STORE_TYPE + value: JKS + - name: KC_LOG_LEVEL + value: INFO + volumeMounts: + - mountPath: /truststore + name: truststore-volume + volumes: + - name: truststore-volume + secret: + secretName: keycloak-truststore +status: \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health.lua b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health.lua new file mode 100644 index 0000000000000..8010a3492453f --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health.lua @@ -0,0 +1,33 @@ +local hs = {} +local healthy = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.status == "False" then + healthy.status = "False" + healthy.message = condition.message + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthy ~= {} and healthy.status == "False") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthy.message + end + return hs + elseif obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "InterStepBufferService is healthy" + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for InterStepBufferService status" +return hs \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health_test.yaml b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health_test.yaml new file mode 100644 index 0000000000000..1c4ff922dabfa --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for InterStepBufferService status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "InterStepBufferService is healthy" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "Waiting for 3 pods to be ready...\n" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/degraded.yaml b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/degraded.yaml new file mode 100644 index 0000000000000..6d35204137733 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/degraded.yaml @@ -0,0 +1,87 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: InterStepBufferService +metadata: + creationTimestamp: "2024-10-08T16:32:12Z" + finalizers: + - isbsvc-controller + generation: 1 + name: test-isbservice-rollout + namespace: numaplane-system + ownerReferences: + - apiVersion: numaplane.numaproj.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: ISBServiceRollout + name: test-isbservice-rollout + uid: 28fc22f1-83f3-441c-bf76-dd4a11ce3891 + resourceVersion: "348334" + uid: 06a5cb44-f3f9-42f8-ab9e-7d2f10323f9e +spec: + jetstream: + containerTemplate: + resources: + limits: + memory: 10Mi + persistence: + volumeSize: 10Mi + version: 2.9.6 +status: + conditions: + - lastTransitionTime: "2024-10-08T16:32:37Z" + message: | + Waiting for 3 pods to be ready... + reason: Unavailable + status: "False" + type: ChildrenResourcesHealthy + - lastTransitionTime: "2024-10-08T16:32:37Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T16:32:37Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + config: + jetstream: + auth: + basic: + password: + key: client-auth-password + name: isbsvc-test-isbservice-rollout-js-client-auth + user: + key: client-auth-user + name: isbsvc-test-isbservice-rollout-js-client-auth + streamConfig: | + consumer: + ackwait: 60s + maxackpending: 25000 + otbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 3h + procbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 72h + stream: + duplicates: 60s + maxage: 72h + maxbytes: -1 + maxmsgs: 100000 + replicas: 3 + retention: 0 + storage: 0 + url: nats://isbsvc-test-isbservice-rollout-js-svc.numaplane-system.svc:4222 + message: | + Unavailable: Waiting for 3 pods to be ready... + observedGeneration: 1 + phase: Running + type: jetstream \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/healthy.yaml b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/healthy.yaml new file mode 100644 index 0000000000000..c37ac31622186 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/healthy.yaml @@ -0,0 +1,78 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: InterStepBufferService +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"InterStepBufferService","metadata":{"annotations":{},"name":"default","namespace":"numaflow-system"},"spec":{"jetstream":{"persistence":{"volumeSize":"3Gi"},"version":"latest"}}} + creationTimestamp: "2024-10-08T18:21:09Z" + finalizers: + - isbsvc-controller + generation: 1 + name: default + namespace: numaflow-system + resourceVersion: "357862" + uid: e175db66-3918-4ef8-993d-12b37eb9a964 +spec: + jetstream: + persistence: + volumeSize: 3Gi + replicas: 3 + version: latest +status: + conditions: + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: | + partitioned roll out complete: 3 new pods have been updated... + reason: Healthy + status: "True" + type: ChildrenResourcesHealthy + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + config: + jetstream: + auth: + basic: + password: + key: client-auth-password + name: isbsvc-default-js-client-auth + user: + key: client-auth-user + name: isbsvc-default-js-client-auth + streamConfig: | + consumer: + ackwait: 60s + maxackpending: 25000 + otbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 3h + procbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 72h + stream: + duplicates: 60s + maxage: 72h + maxbytes: -1 + maxmsgs: 100000 + replicas: 3 + retention: 0 + storage: 0 + url: nats://isbsvc-default-js-svc.numaflow-system.svc:4222 + observedGeneration: 1 + phase: Running + type: jetstream \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/progressing.yaml b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/progressing.yaml new file mode 100644 index 0000000000000..f042b672cb5a4 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/InterStepBufferService/testdata/progressing.yaml @@ -0,0 +1,78 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: InterStepBufferService +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"InterStepBufferService","metadata":{"annotations":{},"name":"default","namespace":"numaflow-system"},"spec":{"jetstream":{"persistence":{"volumeSize":"3Gi"},"version":"latest"}}} + creationTimestamp: "2024-10-08T18:21:09Z" + finalizers: + - isbsvc-controller + generation: 2 + name: default + namespace: numaflow-system + resourceVersion: "357862" + uid: e175db66-3918-4ef8-993d-12b37eb9a964 +spec: + jetstream: + persistence: + volumeSize: 3Gi + replicas: 3 + version: latest +status: + conditions: + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: | + partitioned roll out complete: 3 new pods have been updated... + reason: Healthy + status: "True" + type: ChildrenResourcesHealthy + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:21:53Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + config: + jetstream: + auth: + basic: + password: + key: client-auth-password + name: isbsvc-default-js-client-auth + user: + key: client-auth-user + name: isbsvc-default-js-client-auth + streamConfig: | + consumer: + ackwait: 60s + maxackpending: 25000 + otbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 3h + procbucket: + history: 1 + maxbytes: 0 + maxvaluesize: 0 + replicas: 3 + storage: 0 + ttl: 72h + stream: + duplicates: 60s + maxage: 72h + maxbytes: -1 + maxmsgs: 100000 + replicas: 3 + retention: 0 + storage: 0 + url: nats://isbsvc-default-js-svc.numaflow-system.svc:4222 + observedGeneration: 1 + phase: Running + type: jetstream \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/action_test.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/action_test.yaml new file mode 100644 index 0000000000000..9598f98d22f37 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/action_test.yaml @@ -0,0 +1,7 @@ +actionTests: +- action: pause + inputPath: testdata/monovertex.yaml + expectedOutputPath: testdata/monovertex-paused.yaml +- action: unpause + inputPath: testdata/monovertex-paused.yaml + expectedOutputPath: testdata/monovertex.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/discovery.lua b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/discovery.lua new file mode 100644 index 0000000000000..994ef9723b2c7 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/discovery.lua @@ -0,0 +1,13 @@ +local actions = {} +actions["pause"] = {["disabled"] = true} +actions["unpause"] = {["disabled"] = true} + +local paused = false +if obj.spec.lifecycle ~= nil and obj.spec.lifecycle.desiredPhase ~= nil and obj.spec.lifecycle.desiredPhase == "Paused" then + paused = true +end +if paused then + actions["unpause"]["disabled"] = false +else + actions["pause"]["disabled"] = false +end \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/pause/action.lua b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/pause/action.lua new file mode 100644 index 0000000000000..93d5eeb6fb0a1 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/pause/action.lua @@ -0,0 +1,5 @@ +if obj.spec.lifecycle == nil then + obj.spec.lifecycle = {} + end + obj.spec.lifecycle.desiredPhase = "Paused" + return obj \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex-paused.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex-paused.yaml new file mode 100644 index 0000000000000..ec124964cbfbf --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex-paused.yaml @@ -0,0 +1,55 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + creationTimestamp: "2024-10-09T21:18:37Z" + generation: 1 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "1382" + uid: b7b9e4f8-cd4b-4771-9e4b-2880cc50467a +spec: + lifecycle: + desiredPhase: Paused + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-09T21:18:41Z" + message: Successful + reason: Successful + status: "True" + type: DaemonHealthy + - lastTransitionTime: "2024-10-09T21:18:37Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-09T21:18:37Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-09T21:18:37Z" + lastUpdated: "2024-10-09T21:18:41Z" + observedGeneration: 1 + phase: Running + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReplicas: 1 diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex.yaml new file mode 100644 index 0000000000000..5532b8e81e3de --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/testdata/monovertex.yaml @@ -0,0 +1,55 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + creationTimestamp: "2024-10-09T21:18:37Z" + generation: 1 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "1382" + uid: b7b9e4f8-cd4b-4771-9e4b-2880cc50467a +spec: + lifecycle: + desiredPhase: Running + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-09T21:18:41Z" + message: Successful + reason: Successful + status: "True" + type: DaemonHealthy + - lastTransitionTime: "2024-10-09T21:18:37Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-09T21:18:37Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-09T21:18:37Z" + lastUpdated: "2024-10-09T21:18:41Z" + observedGeneration: 1 + phase: Running + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReplicas: 1 diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/unpause/action.lua b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/unpause/action.lua new file mode 100644 index 0000000000000..2d0265fc4ff4b --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/actions/unpause/action.lua @@ -0,0 +1,2 @@ +obj.spec.lifecycle.desiredPhase = "Running" +return obj \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/health.lua b/resource_customizations/numaflow.numaproj.io/MonoVertex/health.lua new file mode 100644 index 0000000000000..651abcda980d4 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/health.lua @@ -0,0 +1,36 @@ +local hs = {} +local healthy = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.status == "False" then + healthy.status = "False" + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthy ~= {} and healthy.status == "False") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = "Subresources are unhealthy" + end + return hs + elseif obj.status.phase == "Paused" then + hs.status = "Suspended" + hs.message = "MonoVertex is paused" + return hs + elseif obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "MonoVertex is healthy" + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for MonoVertex status" +return hs diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/health_test.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/health_test.yaml new file mode 100644 index 0000000000000..0d771f2924efb --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for MonoVertex status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "MonoVertex is healthy" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "Subresources are unhealthy" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Suspended + message: "MonoVertex is paused" + inputPath: testdata/suspended.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/degraded.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/degraded.yaml new file mode 100644 index 0000000000000..423dc64a32f56 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/degraded.yaml @@ -0,0 +1,61 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"MonoVertex","metadata":{"annotations":{},"name":"simple-mono-vertex","namespace":"numaflow-system"},"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}} + creationTimestamp: "2024-10-08T20:34:32Z" + generation: 1 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "367420" + uid: 7bc9291a-9c80-4ec1-8b06-46fac8f7e507 +spec: + lifecycle: + desiredPhase: Running + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-08T20:34:36Z" + message: 'Waiting for deployment "simple-mono-vertex-mv-daemon" rollout to + finish: 0 out of 1 new replicas have been updated...' + reason: Progressing + status: "False" + type: DaemonHealthy + - lastTransitionTime: "2024-10-08T20:34:32Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T21:58:03Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T20:34:32Z" + lastUpdated: "2024-10-08T21:58:13Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/healthy.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/healthy.yaml new file mode 100644 index 0000000000000..6b6ffd71ba44f --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/healthy.yaml @@ -0,0 +1,60 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"MonoVertex","metadata":{"annotations":{},"name":"simple-mono-vertex","namespace":"numaflow-system"},"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}} + creationTimestamp: "2024-10-08T20:34:32Z" + generation: 1 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "367420" + uid: 7bc9291a-9c80-4ec1-8b06-46fac8f7e507 +spec: + lifecycle: + desiredPhase: Running + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-08T20:34:36Z" + message: Successful + reason: Successful + status: "True" + type: DaemonHealthy + - lastTransitionTime: "2024-10-08T20:34:32Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T21:58:03Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T20:34:32Z" + lastUpdated: "2024-10-08T21:58:13Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/progressing.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/progressing.yaml new file mode 100644 index 0000000000000..00e83e2f8e3ad --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/progressing.yaml @@ -0,0 +1,60 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"MonoVertex","metadata":{"annotations":{},"name":"simple-mono-vertex","namespace":"numaflow-system"},"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}} + creationTimestamp: "2024-10-08T20:34:32Z" + generation: 2 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "367420" + uid: 7bc9291a-9c80-4ec1-8b06-46fac8f7e507 +spec: + lifecycle: + desiredPhase: Running + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-08T20:34:36Z" + message: Successful + reason: Successful + status: "True" + type: DaemonHealthy + - lastTransitionTime: "2024-10-08T20:34:32Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T21:58:03Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T20:34:32Z" + lastUpdated: "2024-10-08T21:58:13Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/suspended.yaml b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/suspended.yaml new file mode 100644 index 0000000000000..a9282f1338a33 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/MonoVertex/testdata/suspended.yaml @@ -0,0 +1,60 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: MonoVertex +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaflow.numaproj.io/v1alpha1","kind":"MonoVertex","metadata":{"annotations":{},"name":"simple-mono-vertex","namespace":"numaflow-system"},"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}} + creationTimestamp: "2024-10-08T20:34:32Z" + generation: 1 + name: simple-mono-vertex + namespace: numaflow-system + resourceVersion: "367420" + uid: 7bc9291a-9c80-4ec1-8b06-46fac8f7e507 +spec: + lifecycle: + desiredPhase: Running + replicas: 1 + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate +status: + conditions: + - lastTransitionTime: "2024-10-08T20:34:36Z" + message: Successful + reason: Successful + status: "True" + type: DaemonHealthy + - lastTransitionTime: "2024-10-08T20:34:32Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T21:58:03Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T20:34:32Z" + lastUpdated: "2024-10-08T21:58:13Z" + observedGeneration: 1 + phase: Paused + readyReplicas: 1 + replicas: 1 + selector: app.kubernetes.io/component=mono-vertex,numaflow.numaproj.io/mono-vertex-name=simple-mono-vertex + updateHash: 8ed34d9058faa60997ee13083ccb3d80691df37b45a34eaa347af99f237e8df6 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/action_test.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/action_test.yaml new file mode 100644 index 0000000000000..e5bd254590394 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/action_test.yaml @@ -0,0 +1,7 @@ +actionTests: +- action: pause + inputPath: testdata/pipeline.yaml + expectedOutputPath: testdata/pipeline-paused.yaml +- action: unpause + inputPath: testdata/pipeline-paused.yaml + expectedOutputPath: testdata/pipeline.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/discovery.lua b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/discovery.lua new file mode 100644 index 0000000000000..994ef9723b2c7 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/discovery.lua @@ -0,0 +1,13 @@ +local actions = {} +actions["pause"] = {["disabled"] = true} +actions["unpause"] = {["disabled"] = true} + +local paused = false +if obj.spec.lifecycle ~= nil and obj.spec.lifecycle.desiredPhase ~= nil and obj.spec.lifecycle.desiredPhase == "Paused" then + paused = true +end +if paused then + actions["unpause"]["disabled"] = false +else + actions["pause"]["disabled"] = false +end \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/pause/action.lua b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/pause/action.lua new file mode 100644 index 0000000000000..91fba1b8694a1 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/pause/action.lua @@ -0,0 +1,5 @@ +if obj.spec.lifecycle == nil then + obj.spec.lifecycle = {} +end +obj.spec.lifecycle.desiredPhase = "Paused" +return obj \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline-paused.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline-paused.yaml new file mode 100644 index 0000000000000..fcef892ea3bcf --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline-paused.yaml @@ -0,0 +1,98 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 1 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "382381" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Paused + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-09T20:26:54Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Running + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline.yaml new file mode 100644 index 0000000000000..8d041623ad1cb --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/testdata/pipeline.yaml @@ -0,0 +1,98 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 1 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "382381" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Running + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-09T20:26:54Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-09T20:26:54Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Running + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/actions/unpause/action.lua b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/unpause/action.lua new file mode 100644 index 0000000000000..2d0265fc4ff4b --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/actions/unpause/action.lua @@ -0,0 +1,2 @@ +obj.spec.lifecycle.desiredPhase = "Running" +return obj \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/health.lua b/resource_customizations/numaflow.numaproj.io/Pipeline/health.lua new file mode 100644 index 0000000000000..a3983e233071b --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/health.lua @@ -0,0 +1,36 @@ +local hs = {} +local healthy = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.status == "False" then + healthy.status = "False" + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthy ~= {} and healthy.status == "False") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = "Subresources are unhealthy" + end + return hs + elseif obj.status.phase == "Paused" or obj.status.phase == "Pausing" then + hs.status = "Suspended" + hs.message = "Pipeline is paused" + return hs + elseif obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Pipeline is healthy" + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Pipeline status" +return hs \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/health_test.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/health_test.yaml new file mode 100644 index 0000000000000..d24709e80c946 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for Pipeline status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Pipeline is healthy" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "Subresources are unhealthy" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Suspended + message: "Pipeline is paused" + inputPath: testdata/suspended.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/degraded.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/degraded.yaml new file mode 100644 index 0000000000000..c11ef0ee21f28 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/degraded.yaml @@ -0,0 +1,99 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 1 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "358080" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Running + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: 'Waiting for deployment "simple-pipeline-daemon" rollout to finish: + 0 of 1 updated replicas are available...' + reason: Progressing + status: "False" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-08T18:22:49Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Running + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/healthy.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/healthy.yaml new file mode 100644 index 0000000000000..3d6c14212a98d --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/healthy.yaml @@ -0,0 +1,98 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 1 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "358080" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Running + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-08T18:22:49Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Running + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/progressing.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/progressing.yaml new file mode 100644 index 0000000000000..5f36b2716f52b --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/progressing.yaml @@ -0,0 +1,98 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 2 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "358080" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Running + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-08T18:22:49Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Running + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/suspended.yaml b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/suspended.yaml new file mode 100644 index 0000000000000..4a2aff55d71e2 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Pipeline/testdata/suspended.yaml @@ -0,0 +1,98 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Pipeline +metadata: + creationTimestamp: "2024-10-08T18:22:18Z" + finalizers: + - pipeline-controller + generation: 1 + name: simple-pipeline + namespace: numaflow-system + resourceVersion: "358080" + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db +spec: + edges: + - from: in + to: cat + - from: cat + to: out + lifecycle: + deleteGracePeriodSeconds: 30 + desiredPhase: Running + pauseGracePeriodSeconds: 30 + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + vertices: + - name: in + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: cat + scale: + min: 1 + udf: + builtin: + name: cat + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + - name: out + scale: + min: 1 + sink: + log: {} + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Configured + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: DaemonServiceHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: No Side Inputs attached to the pipeline + reason: NoSideInputs + status: "True" + type: SideInputsManagersHealthy + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All vertices are healthy + reason: Successful + status: "True" + type: VerticesHealthy + lastUpdated: "2024-10-08T18:22:49Z" + mapUDFCount: 1 + observedGeneration: 1 + phase: Paused + reduceUDFCount: 0 + sinkCount: 1 + sourceCount: 1 + udfCount: 1 + vertexCount: 3 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Vertex/health.lua b/resource_customizations/numaflow.numaproj.io/Vertex/health.lua new file mode 100644 index 0000000000000..6d1f1d093abf8 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Vertex/health.lua @@ -0,0 +1,33 @@ +local hs = {} +local healthy = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.status == "False" then + healthy.status = "False" + healthy.message = condition.message + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthy ~= {} and healthy.status == "False") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthy.message + end + return hs + elseif obj.status.phase == "Running" then + hs.status = "Healthy" + hs.message = "Vertex is healthy" + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Vertex status" +return hs \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Vertex/health_test.yaml b/resource_customizations/numaflow.numaproj.io/Vertex/health_test.yaml new file mode 100644 index 0000000000000..804bf7e1a9bb1 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Vertex/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for Vertex status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Vertex is healthy" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "No Pods found" + inputPath: testdata/degraded.yaml \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Vertex/testdata/degraded.yaml b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/degraded.yaml new file mode 100644 index 0000000000000..5ddb0fb0786f1 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/degraded.yaml @@ -0,0 +1,89 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Vertex +metadata: + annotations: + numaflow.numaproj.io/hash: 49d114791b2e7f2018af5127923f782a5060ff99f50954728ec39acb55fb3962 + creationTimestamp: "2024-10-08T18:22:18Z" + generation: 1 + labels: + app.kubernetes.io/component: vertex + app.kubernetes.io/managed-by: pipeline-controller + app.kubernetes.io/part-of: numaflow + numaflow.numaproj.io/pipeline-name: simple-pipeline + numaflow.numaproj.io/vertex-name: in + name: simple-pipeline-in + namespace: numaflow-system + ownerReferences: + - apiVersion: numaflow.numaproj.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Pipeline + name: simple-pipeline + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db + resourceVersion: "358079" + uid: 24ddb7cc-6e59-4ae1-8faa-e58039615108 +spec: + interStepBufferServiceName: "" + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + name: in + pipelineName: simple-pipeline + replicas: 1 + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + toEdges: + - from: in + fromVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + fromVertexPartitionCount: 1 + fromVertexType: Source + to: cat + toVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + toVertexPartitionCount: 1 + toVertexType: MapUDF + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: No Pods found + reason: NoPodsFound + status: "False" + type: PodsHealthy + currentHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T18:22:18Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: numaflow.numaproj.io/pipeline-name=simple-pipeline,numaflow.numaproj.io/vertex-name=in + updateHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Vertex/testdata/healthy.yaml b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/healthy.yaml new file mode 100644 index 0000000000000..cf74727384c80 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/healthy.yaml @@ -0,0 +1,89 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Vertex +metadata: + annotations: + numaflow.numaproj.io/hash: 49d114791b2e7f2018af5127923f782a5060ff99f50954728ec39acb55fb3962 + creationTimestamp: "2024-10-08T18:22:18Z" + generation: 1 + labels: + app.kubernetes.io/component: vertex + app.kubernetes.io/managed-by: pipeline-controller + app.kubernetes.io/part-of: numaflow + numaflow.numaproj.io/pipeline-name: simple-pipeline + numaflow.numaproj.io/vertex-name: in + name: simple-pipeline-in + namespace: numaflow-system + ownerReferences: + - apiVersion: numaflow.numaproj.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Pipeline + name: simple-pipeline + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db + resourceVersion: "358079" + uid: 24ddb7cc-6e59-4ae1-8faa-e58039615108 +spec: + interStepBufferServiceName: "" + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + name: in + pipelineName: simple-pipeline + replicas: 1 + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + toEdges: + - from: in + fromVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + fromVertexPartitionCount: 1 + fromVertexType: Source + to: cat + toVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + toVertexPartitionCount: 1 + toVertexType: MapUDF + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T18:22:18Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: numaflow.numaproj.io/pipeline-name=simple-pipeline,numaflow.numaproj.io/vertex-name=in + updateHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaflow.numaproj.io/Vertex/testdata/progressing.yaml b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/progressing.yaml new file mode 100644 index 0000000000000..df07d249c9233 --- /dev/null +++ b/resource_customizations/numaflow.numaproj.io/Vertex/testdata/progressing.yaml @@ -0,0 +1,89 @@ +apiVersion: numaflow.numaproj.io/v1alpha1 +kind: Vertex +metadata: + annotations: + numaflow.numaproj.io/hash: 49d114791b2e7f2018af5127923f782a5060ff99f50954728ec39acb55fb3962 + creationTimestamp: "2024-10-08T18:22:18Z" + generation: 2 + labels: + app.kubernetes.io/component: vertex + app.kubernetes.io/managed-by: pipeline-controller + app.kubernetes.io/part-of: numaflow + numaflow.numaproj.io/pipeline-name: simple-pipeline + numaflow.numaproj.io/vertex-name: in + name: simple-pipeline-in + namespace: numaflow-system + ownerReferences: + - apiVersion: numaflow.numaproj.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Pipeline + name: simple-pipeline + uid: bb6cc91c-eb05-4fe7-9380-63b9532a85db + resourceVersion: "358079" + uid: 24ddb7cc-6e59-4ae1-8faa-e58039615108 +spec: + interStepBufferServiceName: "" + limits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + name: in + pipelineName: simple-pipeline + replicas: 1 + scale: + min: 1 + source: + generator: + duration: 1s + jitter: 0s + msgSize: 8 + rpu: 5 + toEdges: + - from: in + fromVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + fromVertexPartitionCount: 1 + fromVertexType: Source + to: cat + toVertexLimits: + bufferMaxLength: 30000 + bufferUsageLimit: 80 + readBatchSize: 500 + readTimeout: 1s + toVertexPartitionCount: 1 + toVertexType: MapUDF + updateStrategy: + rollingUpdate: + maxUnavailable: 25% + type: RollingUpdate + watermark: + disabled: false + maxDelay: 0s +status: + conditions: + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: Successful + reason: Successful + status: "True" + type: Deployed + - lastTransitionTime: "2024-10-08T18:22:49Z" + message: All pods are healthy + reason: Running + status: "True" + type: PodsHealthy + currentHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + desiredReplicas: 1 + lastScaledAt: "2024-10-08T18:22:18Z" + observedGeneration: 1 + phase: Running + readyReplicas: 1 + replicas: 1 + selector: numaflow.numaproj.io/pipeline-name=simple-pipeline,numaflow.numaproj.io/vertex-name=in + updateHash: 283acf2c91c43645fc504622b5d360c7de5dd08e6ff0b100c25e3f0580c92e67 + updatedReadyReplicas: 1 + updatedReplicas: 1 \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua index 1bcd2892b4160..934c59d5859cb 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua @@ -1,32 +1,60 @@ local hs = {} local healthyCondition = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for ISBService status" +hs.status = "Unknown" +hs.message = "Unknown ISBService status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml index b0b683266c6eb..c728c3d300a68 100644 --- a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml @@ -1,21 +1,25 @@ tests: - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/ISBServiceRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/ISBServiceRollout/healthy.yaml - healthStatus: status: Degraded message: "ISBService Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/ISBServiceRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing-nostatus.yaml + message: "Not yet reconciled" + inputPath: testdata/ISBServiceRollout/progressing-nostatus.yaml - healthStatus: status: Progressing - message: "Waiting for ISBService status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/ISBServiceRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..154c91cffffb3 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,40 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest +status: + upgradeInProgress: 'progressive' + conditions: + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-nostatus.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-nostatus.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/ISBServiceRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml new file mode 100644 index 0000000000000..516e32f793df5 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/action_test.yaml @@ -0,0 +1,7 @@ +actionTests: +- action: pause + inputPath: testdata/MonoVertexRollout/rollout.yaml + expectedOutputPath: testdata/MonoVertexRollout/rollout-paused.yaml +- action: unpause + inputPath: testdata/MonoVertexRollout/rollout-paused.yaml + expectedOutputPath: testdata/MonoVertexRollout/rollout-running.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/discovery.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/discovery.lua new file mode 100644 index 0000000000000..2961869dbdcc0 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/discovery.lua @@ -0,0 +1,14 @@ +local actions = {} +actions["pause"] = {["disabled"] = true} +actions["unpause"] = {["disabled"] = true} + +local paused = false +if obj.spec.monoVertex.spec.lifecycle ~= nil and obj.spec.monoVertex.spec.lifecycle.desiredPhase ~= nil and obj.spec.monoVertex.spec.lifecycle.desiredPhase == "Paused" then + paused = true +end +if paused then + actions["unpause"]["disabled"] = false +else + actions["pause"]["disabled"] = false +end +return actions \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/pause/action.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/pause/action.lua new file mode 100644 index 0000000000000..6e86a8dfd29e6 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/pause/action.lua @@ -0,0 +1,5 @@ +if obj.spec.monoVertex.spec.lifecycle == nil then + obj.spec.monoVertex.spec.lifecycle = {} +end +obj.spec.monoVertex.spec.lifecycle.desiredPhase = "Paused" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-paused.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-paused.yaml new file mode 100644 index 0000000000000..2035d668963cc --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-paused.yaml @@ -0,0 +1,49 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + lifecycle: + desiredPhase: Paused + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-running.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-running.yaml new file mode 100644 index 0000000000000..e1f47e521846e --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout-running.yaml @@ -0,0 +1,49 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + lifecycle: + desiredPhase: Running + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/testdata/MonoVertexRollout/rollout.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/unpause/action.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/unpause/action.lua new file mode 100644 index 0000000000000..c5aa23b690586 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/actions/unpause/action.lua @@ -0,0 +1,2 @@ +obj.spec.monoVertex.spec.lifecycle.desiredPhase = "Running" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua index 2e221a7323649..e91efc6ac68ab 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua @@ -1,32 +1,74 @@ local hs = {} local healthyCondition = {} +local monoVertexPaused = {} + +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end - end - end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + if condition.type == "MonoVertexPausingOrPaused" then + monoVertexPaused = condition end end end -hs.status = "Progressing" -hs.message = "Waiting for MonoVertex status" + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif (monoVertexPaused ~= {} and monoVertexPaused.status == "True") then + hs.status = "Suspended" + hs.message = monoVertexPaused.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs +end + + + + + +hs.status = "Unknown" +hs.message = "Unknown MonoVertex status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml index aee12b9ceb9c3..b86d285232d9a 100644 --- a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml @@ -1,17 +1,25 @@ tests: - healthStatus: status: Progressing - message: "Waiting for MonoVertex status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/MonoVertexRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/MonoVertexRollout/healthy.yaml +- healthStatus: + status: Suspended + message: "MonoVertex paused" + inputPath: testdata/MonoVertexRollout/paused.yaml - healthStatus: status: Degraded message: "MonoVertex Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/MonoVertexRollout/degraded.yaml +- healthStatus: + status: Progressing + message: "Progressing" + inputPath: testdata/MonoVertexRollout/progressing-reason.yaml - healthStatus: status: Progressing - message: "Waiting for MonoVertex status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Phase=Pending" + inputPath: testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/healthy.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/healthy.yaml new file mode 100644 index 0000000000000..ee9d76c826dc4 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/healthy.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/paused.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/paused.yaml new file mode 100644 index 0000000000000..0aec918a6b723 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/paused.yaml @@ -0,0 +1,55 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"lifecycle":{"desiredPhase":"Paused"},"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: "2024-10-29T20:44:33Z" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 3 + name: my-monovertex + namespace: example-namespace + resourceVersion: "295152" + uid: b1bc7ad6-4ffe-44e5-ad1f-57455f96921d +spec: + monoVertex: + metadata: {} + spec: + lifecycle: + desiredPhase: Paused + sink: + udsink: + container: + image: quay.io/numaio/numaflow-java/simple-sink:stable + source: + transformer: + container: + image: quay.io/numaio/numaflow-rs/source-transformer-now:stable + udsource: + container: + image: quay.io/numaio/numaflow-java/source-simple-source:stable +status: + conditions: + - lastTransitionTime: "2024-10-29T20:44:33Z" + message: Successful + observedGeneration: 3 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-10-29T20:44:59Z" + message: MonoVertex Pausing - health unknown + observedGeneration: 3 + reason: MonoVertexUnknown + status: Unknown + type: ChildResourcesHealthy + - lastTransitionTime: "2024-10-29T20:44:58Z" + message: MonoVertex paused + observedGeneration: 3 + reason: MonoVertexPaused + status: "True" + type: MonoVertexPausingOrPaused + message: Deployed + nameCount: 1 + observedGeneration: 3 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..ac7e35bd71928 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + upgradeInProgress: progressive + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/MonoVertexRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua index 9ff005740f6e8..4975882d7dea6 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua @@ -1,32 +1,61 @@ local hs = {} local healthyCondition = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + + -- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "True" and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for NumaflowController status" +hs.status = "Unknown" +hs.message = "Unknown NumaflowController status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml index 30bb880f2d38a..ef2778da7dc2b 100644 --- a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml @@ -1,17 +1,21 @@ tests: - healthStatus: status: Progressing - message: "Waiting for NumaflowController status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/NumaflowControllerRollout/progressing-observedgen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/NumaflowControllerRollout/healthy.yaml - healthStatus: status: Degraded message: "no controller definition found for version degraded" - inputPath: testdata/degraded.yaml + inputPath: testdata/NumaflowControllerRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for NumaflowController status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/NumaflowControllerRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/NumaflowControllerRollout/pending.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml new file mode 100644 index 0000000000000..ba49dbc42d844 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/pending.yaml @@ -0,0 +1,36 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"1.2.1"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5456204' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: 1.2.1 +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-observedgen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-observedgen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/NumaflowControllerRollout/progressing-reason.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml new file mode 100644 index 0000000000000..b9652682b8c59 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/action_test.yaml @@ -0,0 +1,13 @@ +actionTests: +- action: pause + inputPath: testdata/PipelineRollout/rollout.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-paused.yaml +- action: unpause + inputPath: testdata/PipelineRollout/rollout-paused.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-running.yaml +- action: allow-data-loss + inputPath: testdata/PipelineRollout/rollout-in-ppnd.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-allowing-data-loss.yaml +- action: disallow-data-loss + inputPath: testdata/PipelineRollout/rollout-allowing-data-loss.yaml + expectedOutputPath: testdata/PipelineRollout/rollout-disallowing-data-loss.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/allow-data-loss/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/allow-data-loss/action.lua new file mode 100644 index 0000000000000..734d1c79fa607 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/allow-data-loss/action.lua @@ -0,0 +1,5 @@ +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["numaplane.numaproj.io/allow-data-loss"] = "true" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disallow-data-loss/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disallow-data-loss/action.lua new file mode 100644 index 0000000000000..0ecfd8856abd1 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/disallow-data-loss/action.lua @@ -0,0 +1,5 @@ +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["numaplane.numaproj.io/allow-data-loss"] = "false" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/discovery.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/discovery.lua new file mode 100644 index 0000000000000..db3cb8b04444e --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/discovery.lua @@ -0,0 +1,26 @@ +local actions = {} +actions["pause"] = {["disabled"] = true} +actions["unpause"] = {["disabled"] = true} +actions["allow-data-loss"] = {["disabled"] = true} +actions["disallow-data-loss"] = {["disabled"] = true} + +-- pause/unpause +local paused = false +if obj.spec.pipeline.spec.lifecycle ~= nil and obj.spec.pipeline.spec.lifecycle.desiredPhase ~= nil and obj.spec.pipeline.spec.lifecycle.desiredPhase == "Paused" then + paused = true +end +if paused then + actions["unpause"]["disabled"] = false +else + actions["pause"]["disabled"] = false +end + +-- allow-data-loss/disallow-data-loss +if obj.status ~= nil and obj.status.upgradeInProgress == "PipelinePauseAndDrain" then + actions["allow-data-loss"]["disabled"] = false +end +if obj.metadata.annotations ~= nil and obj.metadata.annotations["numaplane.numaproj.io/allow-data-loss"] == "true" then + actions["disallow-data-loss"]["disabled"] = false +end + +return actions \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/pause/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/pause/action.lua new file mode 100644 index 0000000000000..d3d378a853527 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/pause/action.lua @@ -0,0 +1,5 @@ +if obj.spec.pipeline.spec.lifecycle == nil then + obj.spec.pipeline.spec.lifecycle = {} +end +obj.spec.pipeline.spec.lifecycle.desiredPhase = "Paused" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-allowing-data-loss.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-allowing-data-loss.yaml new file mode 100644 index 0000000000000..295e7a1f3e906 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-allowing-data-loss.yaml @@ -0,0 +1,85 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + creationTimestamp: "2024-10-02T23:01:46Z" + annotations: + numaplane.numaproj.io/allow-data-loss: "true" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + name: test-pipeline-rollout + namespace: numaplane-system + resourceVersion: "1771" + uid: f89f2135-a6a6-443c-8584-cbf6d789f2db +spec: + pipeline: + spec: + edges: + - conditions: null + from: in + to: cat + - conditions: null + from: cat + to: out + interStepBufferServiceName: test-isbservice-rollout + lifecycle: {} + vertices: + - name: in + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + source: + generator: + duration: 1s + rpu: 5 + updateStrategy: {} + - name: cat + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + udf: + builtin: + name: cat + container: null + groupBy: null + updateStrategy: {} + - name: out + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + sink: + log: {} + retryStrategy: {} + updateStrategy: {} + watermark: {} +status: + conditions: + - lastTransitionTime: "2024-10-02T23:01:46Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline Progressing + observedGeneration: 2 + reason: Progressing + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline pausing + observedGeneration: 2 + reason: PipelinePausing + status: "True" + type: PipelinePausingOrPaused + message: Progressing + nameCount: 0 + observedGeneration: 2 + pauseStatus: + lastPauseBeginTime: "2024-10-02T23:02:41Z" + lastPauseEndTime: null + phase: Pending + upgradeInProgress: PipelinePauseAndDrain \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disallowing-data-loss.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disallowing-data-loss.yaml new file mode 100644 index 0000000000000..df75a28c6b53d --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-disallowing-data-loss.yaml @@ -0,0 +1,85 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + creationTimestamp: "2024-10-02T23:01:46Z" + annotations: + numaplane.numaproj.io/allow-data-loss: "false" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + name: test-pipeline-rollout + namespace: numaplane-system + resourceVersion: "1771" + uid: f89f2135-a6a6-443c-8584-cbf6d789f2db +spec: + pipeline: + spec: + edges: + - conditions: null + from: in + to: cat + - conditions: null + from: cat + to: out + interStepBufferServiceName: test-isbservice-rollout + lifecycle: {} + vertices: + - name: in + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + source: + generator: + duration: 1s + rpu: 5 + updateStrategy: {} + - name: cat + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + udf: + builtin: + name: cat + container: null + groupBy: null + updateStrategy: {} + - name: out + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + sink: + log: {} + retryStrategy: {} + updateStrategy: {} + watermark: {} +status: + conditions: + - lastTransitionTime: "2024-10-02T23:01:46Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline Progressing + observedGeneration: 2 + reason: Progressing + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline pausing + observedGeneration: 2 + reason: PipelinePausing + status: "True" + type: PipelinePausingOrPaused + message: Progressing + nameCount: 0 + observedGeneration: 2 + pauseStatus: + lastPauseBeginTime: "2024-10-02T23:02:41Z" + lastPauseEndTime: null + phase: Pending + upgradeInProgress: PipelinePauseAndDrain \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-in-ppnd.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-in-ppnd.yaml new file mode 100644 index 0000000000000..21660f0b58f2f --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-in-ppnd.yaml @@ -0,0 +1,83 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + creationTimestamp: "2024-10-02T23:01:46Z" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + name: test-pipeline-rollout + namespace: numaplane-system + resourceVersion: "1771" + uid: f89f2135-a6a6-443c-8584-cbf6d789f2db +spec: + pipeline: + spec: + edges: + - conditions: null + from: in + to: cat + - conditions: null + from: cat + to: out + interStepBufferServiceName: test-isbservice-rollout + lifecycle: {} + vertices: + - name: in + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + source: + generator: + duration: 1s + rpu: 5 + updateStrategy: {} + - name: cat + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + udf: + builtin: + name: cat + container: null + groupBy: null + updateStrategy: {} + - name: out + scale: + max: 1 + min: 1 + zeroReplicaSleepSeconds: 15 + sink: + log: {} + retryStrategy: {} + updateStrategy: {} + watermark: {} +status: + conditions: + - lastTransitionTime: "2024-10-02T23:01:46Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline Progressing + observedGeneration: 2 + reason: Progressing + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-10-02T23:02:41Z" + message: Pipeline pausing + observedGeneration: 2 + reason: PipelinePausing + status: "True" + type: PipelinePausingOrPaused + message: Progressing + nameCount: 0 + observedGeneration: 2 + pauseStatus: + lastPauseBeginTime: "2024-10-02T23:02:41Z" + lastPauseEndTime: null + phase: Pending + upgradeInProgress: PipelinePauseAndDrain \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-paused.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-paused.yaml new file mode 100644 index 0000000000000..ac89952fbca54 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-paused.yaml @@ -0,0 +1,63 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{},"name":"my-pipeline","namespace":"example-namespace"},"spec":{"pipeline":{"spec":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"1s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}}]}}}} + creationTimestamp: "2024-09-26T20:54:55Z" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + name: my-pipeline + namespace: example-namespace + resourceVersion: "14008" + uid: ab9286a1-f453-433e-846e-48900ab2068a +spec: + pipeline: + spec: + lifecycle: + desiredPhase: Paused + edges: + - from: in + to: cat + - from: cat + to: out + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 1s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} +status: + conditions: + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-09-26T20:55:07Z" + message: Pipeline Phase=Failed + observedGeneration: 1 + reason: PipelineFailed + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Pipeline unpaused + observedGeneration: 1 + reason: Unpaused + status: "False" + type: PipelinePausingOrPaused + message: Deployed + nameCount: 0 + observedGeneration: 1 + pauseStatus: {} + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-running.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-running.yaml new file mode 100644 index 0000000000000..81504a82da4df --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout-running.yaml @@ -0,0 +1,63 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{},"name":"my-pipeline","namespace":"example-namespace"},"spec":{"pipeline":{"spec":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"1s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}}]}}}} + creationTimestamp: "2024-09-26T20:54:55Z" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + name: my-pipeline + namespace: example-namespace + resourceVersion: "14008" + uid: ab9286a1-f453-433e-846e-48900ab2068a +spec: + pipeline: + spec: + lifecycle: + desiredPhase: Running + edges: + - from: in + to: cat + - from: cat + to: out + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 1s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} +status: + conditions: + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-09-26T20:55:07Z" + message: Pipeline Phase=Failed + observedGeneration: 1 + reason: PipelineFailed + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Pipeline unpaused + observedGeneration: 1 + reason: Unpaused + status: "False" + type: PipelinePausingOrPaused + message: Deployed + nameCount: 0 + observedGeneration: 1 + pauseStatus: {} + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout.yaml new file mode 100644 index 0000000000000..7011e9fd73bad --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/testdata/PipelineRollout/rollout.yaml @@ -0,0 +1,61 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{},"name":"my-pipeline","namespace":"example-namespace"},"spec":{"pipeline":{"spec":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"1s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}}]}}}} + creationTimestamp: "2024-09-26T20:54:55Z" + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + name: my-pipeline + namespace: example-namespace + resourceVersion: "14008" + uid: ab9286a1-f453-433e-846e-48900ab2068a +spec: + pipeline: + spec: + edges: + - from: in + to: cat + - from: cat + to: out + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 1s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} +status: + conditions: + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Successful + observedGeneration: 1 + reason: Successful + status: "True" + type: ChildResourceDeployed + - lastTransitionTime: "2024-09-26T20:55:07Z" + message: Pipeline Phase=Failed + observedGeneration: 1 + reason: PipelineFailed + status: "False" + type: ChildResourcesHealthy + - lastTransitionTime: "2024-09-26T20:54:55Z" + message: Pipeline unpaused + observedGeneration: 1 + reason: Unpaused + status: "False" + type: PipelinePausingOrPaused + message: Deployed + nameCount: 0 + observedGeneration: 1 + pauseStatus: {} + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/unpause/action.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/unpause/action.lua new file mode 100644 index 0000000000000..5f0802bc9b743 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/actions/unpause/action.lua @@ -0,0 +1,2 @@ +obj.spec.pipeline.spec.lifecycle.desiredPhase = "Running" +return obj \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua index 649cbb643d7f9..2fa58a94b0bfe 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua @@ -2,39 +2,68 @@ local hs = {} local healthyCondition = {} local pipelinePaused = {} -if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "ChildResourcesHealthy" then - healthyCondition = condition - end - if condition.type == "PipelinePausingOrPaused" then - pipelinePaused = condition - end +-- check for certain cases of "Progressing" + +if obj.status == nil then -- if there's no Status at all, we haven't been reconciled + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.metadata.generation ~= obj.status.observedGeneration then + hs.status = "Progressing" + hs.message = "Not yet reconciled" + return hs +end + +if obj.status.phase == "Pending" then + hs.status = "Progressing" + hs.message = "Phase=Pending" + return hs +end + +if obj.status.upgradeInProgress ~= nil and obj.status.upgradeInProgress ~= "" then + hs.status = "Progressing" + hs.message = "Update in progress" + return hs +end + +-- now check the Conditions + +if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + if condition.type == "PipelinePausingOrPaused" then + pipelinePaused = condition end end +end - if obj.metadata.generation == obj.status.observedGeneration then - if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then - hs.status = "Degraded" - if obj.status.phase == "Failed" then - hs.message = obj.status.message - else - hs.message = healthyCondition.message - end - return hs - elseif (pipelinePaused ~= {} and pipelinePaused.status == "True") and (obj.metadata.generation == pipelinePaused.observedGeneration) then - hs.status = "Suspended" - hs.message = pipelinePaused.message - return hs - elseif (healthyCondition ~= {} and healthyCondition.status == "True") and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then - hs.status = "Healthy" - hs.message = healthyCondition.message - return hs - end + +if (healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message end + return hs +elseif healthyCondition ~= {} and healthyCondition.status == "False" and healthyCondition.reason == "Progressing" then + hs.status = "Progressing" + hs.message = healthyCondition.message + return hs +elseif (pipelinePaused ~= {} and pipelinePaused.status == "True") then + hs.status = "Suspended" + hs.message = pipelinePaused.message + return hs +elseif (healthyCondition ~= {} and healthyCondition.status == "True") and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs end -hs.status = "Progressing" -hs.message = "Waiting for Pipeline status" +hs.status = "Unknown" +hs.message = "Unknown Pipeline status" return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml index 99274d213992b..3ff01e4435656 100644 --- a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml @@ -1,21 +1,25 @@ tests: - healthStatus: status: Progressing - message: "Waiting for Pipeline status" - inputPath: testdata/progressing.yaml + message: "Not yet reconciled" + inputPath: testdata/PipelineRollout/progressing-observedGen.yaml - healthStatus: status: Healthy message: "Successful" - inputPath: testdata/healthy.yaml + inputPath: testdata/PipelineRollout/healthy.yaml - healthStatus: status: Suspended message: "Pipeline paused" - inputPath: testdata/paused.yaml + inputPath: testdata/PipelineRollout/paused.yaml - healthStatus: status: Degraded message: "Pipeline Failed" - inputPath: testdata/degraded.yaml + inputPath: testdata/PipelineRollout/degraded.yaml - healthStatus: status: Progressing - message: "Waiting for Pipeline status" - inputPath: testdata/progressing-reason.yaml \ No newline at end of file + message: "Progressing" + inputPath: testdata/PipelineRollout/progressing-reason.yaml +- healthStatus: + status: Progressing + message: "Phase=Pending" + inputPath: testdata/PipelineRollout/pending-upgrade-in-progress.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/degraded.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/degraded.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/healthy.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/healthy.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/paused.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/paused.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml new file mode 100644 index 0000000000000..2731f79aeb9de --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/pending-upgrade-in-progress.yaml @@ -0,0 +1,60 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5456110' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + upgradeInProgress: 'progressive' + conditions: + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Pending \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-observedGen.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-observedGen.yaml diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-reason.yaml similarity index 100% rename from resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml rename to resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/PipelineRollout/progressing-reason.yaml diff --git a/resource_customizations/platform.confluent.io/Connector/health.lua b/resource_customizations/platform.confluent.io/Connector/health.lua new file mode 100644 index 0000000000000..a800a33179d30 --- /dev/null +++ b/resource_customizations/platform.confluent.io/Connector/health.lua @@ -0,0 +1,25 @@ +hs = {} +if obj.status ~= nil and obj.status.state ~= nil then + if obj.status.state == "CREATED" and obj.status.connectorState == "RUNNING" and obj.status.failedTasksCount == nil then + hs.status = "Healthy" + hs.message = "Connector running" + return hs + end + if obj.status.state == "ERROR" then + hs.status = "Degraded" + if obj.status.conditions and #obj.status.conditions > 0 then + hs.message = obj.status.conditions[1].message -- Kafka Connector only has one condition and nests the issues in the error message here + else + hs.message = "No conditions available" + end + return hs + end + if obj.status.failedTasksCount ~= nil and obj.status.failedTasksCount > 0 then + hs.status = "Degraded" + hs.message = "Connector has failed tasks" + return hs + end +end +hs.status = "Progressing" +hs.message = "Waiting for Kafka Connector" +return hs \ No newline at end of file diff --git a/resource_customizations/platform.confluent.io/Connector/health_test.yaml b/resource_customizations/platform.confluent.io/Connector/health_test.yaml new file mode 100644 index 0000000000000..c449ba98195e1 --- /dev/null +++ b/resource_customizations/platform.confluent.io/Connector/health_test.yaml @@ -0,0 +1,13 @@ +tests: + - healthStatus: + status: Healthy + message: 'Connector running' + inputPath: testdata/connector-healthy.yaml + - healthStatus: + status: Degraded + message: 'connect Rest API request failed: Connector configuration is invalid and contains the following 1 error(s): Could not read properties from file' + inputPath: testdata/connector-failure.yaml + - healthStatus: + status: Degraded + message: 'Connector has failed tasks' + inputPath: testdata/connector-task-failure.yaml \ No newline at end of file diff --git a/resource_customizations/platform.confluent.io/Connector/testdata/connector-failure.yaml b/resource_customizations/platform.confluent.io/Connector/testdata/connector-failure.yaml new file mode 100644 index 0000000000000..b34a297bbabb9 --- /dev/null +++ b/resource_customizations/platform.confluent.io/Connector/testdata/connector-failure.yaml @@ -0,0 +1,27 @@ +apiVersion: platform.confluent.io/v1beta1 +kind: Connector +metadata: + finalizers: + - connect.finalizers.platform.confluent.io + generation: 1 + name: connect + namespace: confluent +spec: + class: io.confluent.connect.sftp.SftpSinkConnector + configs: + topics: test-topic + connectClusterRef: + name: connect + name: test-sftp-connector + taskMax: 3 +status: + appState: Failed + conditions: + - lastProbeTime: '2024-04-02T07:43:35Z' + lastTransitionTime: '2024-04-02T07:43:35Z' + message: >- + connect Rest API request failed: Connector configuration is invalid and contains the following 1 error(s): Could not read properties from file + reason: CreateFailed + status: 'False' + type: platform.confluent.io/app-ready + state: ERROR \ No newline at end of file diff --git a/resource_customizations/platform.confluent.io/Connector/testdata/connector-healthy.yaml b/resource_customizations/platform.confluent.io/Connector/testdata/connector-healthy.yaml new file mode 100644 index 0000000000000..10df701b7c53e --- /dev/null +++ b/resource_customizations/platform.confluent.io/Connector/testdata/connector-healthy.yaml @@ -0,0 +1,31 @@ +apiVersion: platform.confluent.io/v1beta1 +kind: Connector +metadata: + finalizers: + - connect.finalizers.platform.confluent.io + generation: 1 + name: connect + namespace: confluent +spec: + class: io.confluent.connect.sftp.SftpSinkConnector + configs: + topics: test-topic + connectClusterRef: + name: connect + name: test-sftp-connector + taskMax: 3 +status: + appState: Created + conditions: + - lastProbeTime: '2024-04-02T07:43:35Z' + lastTransitionTime: '2024-04-02T07:43:35Z' + message: Application is created + reason: Created + status: 'True' + type: platform.confluent.io/app-ready + connectorState: RUNNING + restartPolicy: + maxRetry: 10 + type: OnFailure + state: CREATED + tasksReady: 3/3 \ No newline at end of file diff --git a/resource_customizations/platform.confluent.io/Connector/testdata/connector-task-failure.yaml b/resource_customizations/platform.confluent.io/Connector/testdata/connector-task-failure.yaml new file mode 100644 index 0000000000000..09134a48f41b2 --- /dev/null +++ b/resource_customizations/platform.confluent.io/Connector/testdata/connector-task-failure.yaml @@ -0,0 +1,37 @@ +apiVersion: platform.confluent.io/v1beta1 +kind: Connector +metadata: + finalizers: + - connect.finalizers.platform.confluent.io + generation: 1 + name: connect + namespace: confluent +spec: + class: io.confluent.connect.sftp.SftpSinkConnector + configs: + topics: test-topic + connectClusterRef: + name: connect + name: test-sftp-connector + taskMax: 3 +status: + appState: Unknown + conditions: + - lastProbeTime: '2024-01-19T06:42:40Z' + lastTransitionTime: '2024-01-19T06:42:40Z' + message: Application is created + reason: Created + status: 'True' + type: platform.confluent.io/app-ready + connectorState: RUNNING + failedTasks: + task-0: + id: 0 + retryCount: 10 + failedTasksCount: 1 + observedGeneration: 1 + restartPolicy: + maxRetry: 10 + type: OnFailure + state: CREATED + tasksReady: 0/1 \ No newline at end of file diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/health.lua b/resource_customizations/policy.open-cluster-management.io/Policy/health.lua index 9b43c04c4b5e7..b969c367e121e 100644 --- a/resource_customizations/policy.open-cluster-management.io/Policy/health.lua +++ b/resource_customizations/policy.open-cluster-management.io/Policy/health.lua @@ -14,10 +14,10 @@ if obj.status.status ~= nil then -- "root" policy for i, entry in ipairs(obj.status.status) do if entry.compliant ~= "Compliant" then - noncompliants[i] = entry.clustername + table.insert(noncompliants, entry.clustername) end end - if table.getn(noncompliants) == 0 then + if #noncompliants == 0 then hs.message = "All clusters are compliant" else hs.message = "NonCompliant clusters: " .. table.concat(noncompliants, ", ") @@ -26,10 +26,10 @@ elseif obj.status.details ~= nil then -- "replicated" policy for i, entry in ipairs(obj.status.details) do if entry.compliant ~= "Compliant" then - noncompliants[i] = entry.templateMeta.name + table.insert(noncompliants, entry.templateMeta.name) end end - if table.getn(noncompliants) == 0 then + if #noncompliants == 0 then hs.message = "All templates are compliant" else hs.message = "NonCompliant templates: " .. table.concat(noncompliants, ", ") diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated_compliant_before_noncompliant.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated_compliant_before_noncompliant.yaml new file mode 100644 index 0000000000000..d0c3c9aebe558 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated_compliant_before_noncompliant.yaml @@ -0,0 +1,88 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: open-cluster-management-global-set.argo-example + namespace: local-cluster + labels: + policy.open-cluster-management.io/cluster-name: local-cluster + policy.open-cluster-management.io/cluster-namespace: local-cluster + policy.open-cluster-management.io/root-policy: open-cluster-management-global-set.argo-example +spec: + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-namespace + spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: example + remediationAction: inform + severity: low + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-pod + spec: + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: foobar + spec: + containers: + - image: 'registry.redhat.io/rhel9/httpd-24:latest' + name: httpd + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + runAsNonRoot: true + remediationAction: enforce + severity: low +status: + compliant: NonCompliant + details: + - compliant: Compliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e7034c879045a3 + lastTimestamp: '2024-07-30T14:16:49Z' + message: 'Compliant; notification - pods [foobar] was created successfully in namespace default' + templateMeta: + creationTimestamp: null + name: example-foo + - compliant: NonCompliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e701cc5101e3a4 + lastTimestamp: '2024-07-30T13:49:19Z' + message: 'NonCompliant; violation - namespaces [example] not found' + templateMeta: + creationTimestamp: null + name: example-namespace + - compliant: Compliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e7034c879045a3 + lastTimestamp: '2024-07-30T14:16:49Z' + message: 'Compliant; notification - pods [foobar] was created successfully in namespace default' + - eventName: open-cluster-management-global-set.argo-example.17e7020b47782ddc + lastTimestamp: '2024-07-30T13:53:49Z' + message: 'NonCompliant; violation - pods [foobar] not found in namespace default' + templateMeta: + creationTimestamp: null + name: example-pod diff --git a/resource_customizations/policy/PodDisruptionBudget/health.lua b/resource_customizations/policy/PodDisruptionBudget/health.lua index afaa61752cb67..594bdd3b897bf 100644 --- a/resource_customizations/policy/PodDisruptionBudget/health.lua +++ b/resource_customizations/policy/PodDisruptionBudget/health.lua @@ -7,12 +7,13 @@ hs.message = "Waiting for status" if obj.status ~= nil then if obj.status.conditions ~= nil then for i, condition in ipairs(obj.status.conditions) do - if condition.status == "False" then + -- InsufficientPods can have valid use cases + -- See a discussion in https://github.com/argoproj/argo-cd/issues/20171 for more details + if condition.status == "False" and condition.reason ~= "InsufficientPods" then hs.status = "Degraded" hs.message = "PodDisruptionBudget has " .. condition.reason return hs - end - if condition.status == "True" then + else hs.status = "Healthy" hs.message = "PodDisruptionBudget has " .. condition.reason end diff --git a/resource_customizations/policy/PodDisruptionBudget/health_test.yaml b/resource_customizations/policy/PodDisruptionBudget/health_test.yaml index 3ad31b60186ee..817c26a4c3092 100644 --- a/resource_customizations/policy/PodDisruptionBudget/health_test.yaml +++ b/resource_customizations/policy/PodDisruptionBudget/health_test.yaml @@ -9,5 +9,5 @@ tests: inputPath: testdata/progressing.yaml - healthStatus: status: Degraded - message: 'PodDisruptionBudget has InsufficientPods' + message: 'PodDisruptionBudget has SyncFailed' inputPath: testdata/degraded.yaml diff --git a/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml b/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml index 2c2a854e8bc52..1a95f19597e0d 100644 --- a/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml +++ b/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml @@ -16,6 +16,12 @@ status: reason: InsufficientPods status: "False" type: DisruptionAllowed + - lastTransitionTime: "2024-09-06T18:29:06Z" + message: "" + observedGeneration: 2 + reason: SyncFailed + status: "False" + type: DisruptionAllowed currentHealthy: 2 desiredHealthy: 3 disruptionsAllowed: 0 diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health.lua b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health.lua new file mode 100644 index 0000000000000..48ef1a8aea9d6 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health.lua @@ -0,0 +1,18 @@ +local hs = {} +if obj.status ~= nil then + local state_map = { + initializing = "Progressing", + ready = "Healthy", + error = "Degraded", + stopping = "Progressing", + paused = "Suspended" + } + + hs.status = state_map[obj.status.state] or "Unknown" + hs.message = obj.status.ready .. "/" .. obj.status.size .. " node(s) are ready" + return hs +end + +hs.status = "Unknown" +hs.message = "Cluster status is unknown" +return hs diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health_test.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health_test.yaml new file mode 100644 index 0000000000000..7949e34ec4ce9 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/health_test.yaml @@ -0,0 +1,25 @@ +tests: +- healthStatus: + status: Progressing + message: "0/9 node(s) are ready" + inputPath: testdata/initializing.yaml +- healthStatus: + status: Healthy + message: "9/9 node(s) are ready" + inputPath: testdata/ready.yaml +- healthStatus: + status: Suspended + message: "0/9 node(s) are ready" + inputPath: testdata/paused.yaml +- healthStatus: + status: Progressing + message: "6/9 node(s) are ready" + inputPath: testdata/stopping.yaml +- healthStatus: + status: Degraded + message: "0/9 node(s) are ready" + inputPath: testdata/error.yaml +- healthStatus: + status: Unknown + message: "0/0 node(s) are ready" + inputPath: testdata/unknown.yaml diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/error.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/error.yaml new file mode 100644 index 0000000000000..74914f3c55ca8 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/error.yaml @@ -0,0 +1,25 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + mongos: + ready: 0 + size: 3 + status: error + observedGeneration: 1 + ready: 0 + replsets: + cfg: + initialized: true + ready: 0 + size: 3 + status: error + rs0: + initialized: true + ready: 0 + size: 3 + status: error + size: 9 + state: error diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/initializing.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/initializing.yaml new file mode 100644 index 0000000000000..a59e055f3d7e7 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/initializing.yaml @@ -0,0 +1,25 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + mongos: + ready: 0 + size: 3 + status: initializing + observedGeneration: 1 + ready: 0 + replsets: + cfg: + initialized: false + ready: 0 + size: 3 + status: initializing + rs0: + initialized: false + ready: 0 + size: 3 + status: initializing + size: 9 + state: initializing diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/paused.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/paused.yaml new file mode 100644 index 0000000000000..722cc2536fbce --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/paused.yaml @@ -0,0 +1,25 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + mongos: + ready: 0 + size: 3 + status: paused + observedGeneration: 1 + ready: 0 + replsets: + cfg: + initialized: true + ready: 0 + size: 3 + status: paused + rs0: + initialized: true + ready: 0 + size: 3 + status: paused + size: 9 + state: paused diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/ready.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/ready.yaml new file mode 100644 index 0000000000000..9d3b62a7fb640 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/ready.yaml @@ -0,0 +1,25 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + mongos: + ready: 3 + size: 3 + status: ready + observedGeneration: 1 + ready: 9 + replsets: + cfg: + initialized: true + ready: 3 + size: 3 + status: ready + rs0: + initialized: true + ready: 3 + size: 3 + status: ready + size: 9 + state: ready diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/stopping.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/stopping.yaml new file mode 100644 index 0000000000000..d4f7f3ae03eba --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/stopping.yaml @@ -0,0 +1,25 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + mongos: + ready: 2 + size: 3 + status: stopping + observedGeneration: 1 + ready: 6 + replsets: + cfg: + initialized: true + ready: 2 + size: 3 + status: stopping + rs0: + initialized: true + ready: 2 + size: 3 + status: stopping + size: 9 + state: stopping diff --git a/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/unknown.yaml b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/unknown.yaml new file mode 100644 index 0000000000000..7b06350e18023 --- /dev/null +++ b/resource_customizations/psmdb.percona.com/PerconaServerMongoDB/testdata/unknown.yaml @@ -0,0 +1,10 @@ +apiVersion: psmdb.percona.com/v1 +kind: PerconaServerMongoDB +metadata: + name: cluster +spec: {} +status: + observedGeneration: 1 + ready: 0 + size: 0 + state: "" diff --git a/resource_customizations/serving.kserve.io/InferenceService/health.lua b/resource_customizations/serving.kserve.io/InferenceService/health.lua index 85da1161f315f..94959de841d59 100644 --- a/resource_customizations/serving.kserve.io/InferenceService/health.lua +++ b/resource_customizations/serving.kserve.io/InferenceService/health.lua @@ -1,50 +1,59 @@ --- isInferenceServiceInRawDeploymentMode determines if the inference service deployed in RawDeployment mode --- KServe v12 and above supports Rawdeployment for Inference graphs. For Inference services, KServe has supported RawDeployment model since [v0.7.0](https://github.com/kserve/kserve/releases/tag/v0.7.0). -function isInferenceServiceInRawDeploymentMode(obj) - if obj.metadata.annotations == nil then - return false - end - local deploymentMode = obj.metadata.annotations["serving.kserve.io/deploymentMode"] - return deploymentMode ~= nil and deploymentMode == "RawDeployment" -end - local health_status = {} + health_status.status = "Progressing" -health_status.message = "Waiting for status update." -if obj.status ~= nil and obj.status.conditions ~= nil then - local status_true = 0 +health_status.message = "Waiting for InferenceService to report status..." + +if obj.status ~= nil then + + local progressing = false + local degraded = false local status_false = 0 local status_unknown = 0 - health_status.message = "" - for i, condition in pairs(obj.status.conditions) do - if condition.status == "True" and (condition.type == "IngressReady" or condition.type == "PredictorConfigurationReady" or condition.type == "PredictorReady" or condition.type == "PredictorRouteReady" or condition.type == "Ready") then - status_true = status_true + 1 - elseif condition.status == "False" or condition.status == "Unknown" then - msg = condition.type .. " is " .. condition.status - if condition.reason ~= nil and condition.reason ~= "" then - msg = msg .. ", since " .. condition.reason .. "." - end - if condition.message ~= nil and condition.message ~= "" then - msg = msg .. " " .. condition.message - end - health_status.message = health_status.message .. msg .. "\n" - if condition.status == "False" then - status_false = status_false + 1 + local msg = "" + + if obj.status.modelStatus ~= nil then + if obj.status.modelStatus.transitionStatus ~= "UpToDate" then + if obj.status.modelStatus.transitionStatus == "InProgress" then + progressing = true else - status_unknown = status_unknown + 1 + degraded = true end + msg = msg .. "0: transitionStatus | " .. obj.status.modelStatus.transitionStatus end end - if ((isInferenceServiceInRawDeploymentMode(obj) and status_true == 3) or status_true == 5) and status_false == 0 and status_unknown == 0 then - health_status.message = "Inference Service is healthy." - health_status.status = "Healthy" - return health_status - elseif status_false > 0 then - health_status.status = "Degraded" - return health_status - else - health_status.status = "Progressing" - return health_status + + if obj.status.conditions ~= nil then + for i, condition in pairs(obj.status.conditions) do + + if condition.status == "Unknown" then + status_unknown = status_unknown + 1 + elseif condition.status == "False" then + status_false = status_false + 1 + end + + if condition.status ~= "True" then + msg = msg .. " | " .. i .. ": " .. condition.type .. " | " .. condition.status + if condition.reason ~= nil and condition.reason ~= "" then + msg = msg .. " | " .. condition.reason + end + if condition.message ~= nil and condition.message ~= "" then + msg = msg .. " | " .. condition.message + end + end + + end + + if progressing == false and degraded == false and status_unknown == 0 and status_false == 0 then + health_status.status = "Healthy" + msg = "InferenceService is healthy." + elseif degraded == false and status_unknown >= 0 then + health_status.status = "Progressing" + else + health_status.status = "Degraded" + end + + health_status.message = msg end end -return health_status \ No newline at end of file + +return health_status diff --git a/resource_customizations/serving.kserve.io/InferenceService/health_test.yaml b/resource_customizations/serving.kserve.io/InferenceService/health_test.yaml index 1dc5576f93f3a..670b194f79d41 100644 --- a/resource_customizations/serving.kserve.io/InferenceService/health_test.yaml +++ b/resource_customizations/serving.kserve.io/InferenceService/health_test.yaml @@ -1,17 +1,41 @@ tests: - healthStatus: status: Progressing - message: "PredictorConfigurationReady is Unknown\nPredictorReady is Unknown, since RevisionMissing. Configuration \"hello-world-predictor-default\" is waiting for a Revision to become ready.\nPredictorRouteReady is Unknown, since RevisionMissing. Configuration \"hello-world-predictor-default\" is waiting for a Revision to become ready.\nReady is Unknown, since RevisionMissing. Configuration \"hello-world-predictor-default\" is waiting for a Revision to become ready.\n" + message: ' | 1: PredictorConfigurationReady | Unknown | 2: PredictorReady | Unknown | RevisionMissing | Configuration "hello-world-predictor-default" is waiting for a Revision to become ready. | 3: PredictorRouteReady | Unknown | RevisionMissing | Configuration "hello-world-predictor-default" is waiting for a Revision to become ready. | 4: Ready | Unknown | RevisionMissing | Configuration "hello-world-predictor-default" is waiting for a Revision to become ready.' inputPath: testdata/progressing.yaml +- healthStatus: + status: Progressing + message: '0: transitionStatus | InProgress | 1: LatestDeploymentReady | Unknown | PredictorConfigurationReady not ready | 2: PredictorConfigurationReady | Unknown | 3: PredictorReady | Unknown | RevisionMissing | Configuration "helloworld-predictor" is waiting for a Revision to become ready. | 4: PredictorRouteReady | Unknown | RevisionMissing | Configuration "helloworld-predictor" is waiting for a Revision to become ready. | 5: Ready | Unknown | RevisionMissing | Configuration "helloworld-predictor" is waiting for a Revision to become ready. | 6: RoutesReady | Unknown | PredictorRouteReady not ready' + inputPath: testdata/progressing_ocp.yaml +- healthStatus: + status: Progressing + message: "0: transitionStatus | InProgress | 1: PredictorReady | False | 2: Ready | False" + inputPath: testdata/progressing_modelmesh.yaml - healthStatus: status: Degraded - message: "IngressReady is False, since Predictor ingress not created.\nPredictorConfigurationReady is False, since RevisionFailed. Revision \"helloworld-00002\" failed with message: Container failed with: container exited with no error.\nPredictorReady is False, since RevisionFailed. Revision \"helloworld-00002\" failed with message: Container failed with: container exited with no error.\nReady is False, since Predictor ingress not created.\n" + message: '0: transitionStatus | BlockedByFailedLoad | 1: IngressReady | False | Predictor ingress not created | 2: PredictorConfigurationReady | False | RevisionFailed | Revision "helloworld-00002" failed with message: Container failed with: container exited with no error. | 3: PredictorReady | False | RevisionFailed | Revision "helloworld-00002" failed with message: Container failed with: container exited with no error. | 5: Ready | False | Predictor ingress not created' inputPath: testdata/degraded.yaml +- healthStatus: + status: Degraded + message: '0: transitionStatus | BlockedByFailedLoad | 1: LatestDeploymentReady | False | PredictorConfigurationReady not ready | 2: PredictorConfigurationReady | False | RevisionFailed | Revision "helloworld-predictor-00002" failed with message: . | 3: PredictorReady | False | RevisionMissing | Configuration "helloworld-predictor" does not have any ready Revision. | 4: PredictorRouteReady | False | RevisionMissing | Configuration "helloworld-predictor" does not have any ready Revision. | 5: Ready | False | RevisionMissing | Configuration "helloworld-predictor" does not have any ready Revision. | 6: RoutesReady | False | PredictorRouteReady not ready' + inputPath: testdata/degraded_ocp.yaml +- healthStatus: + status: Degraded + message: "0: transitionStatus | BlockedByFailedLoad" + inputPath: testdata/degraded_modelmesh.yaml - healthStatus: status: Healthy - message: Inference Service is healthy. + message: InferenceService is healthy. inputPath: testdata/healthy.yaml - healthStatus: status: Healthy - message: Inference Service is healthy. + message: InferenceService is healthy. + inputPath: testdata/healthy_ocp.yaml +- healthStatus: + status: Healthy + message: InferenceService is healthy. + inputPath: testdata/healthy_modelmesh.yaml +- healthStatus: + status: Healthy + message: InferenceService is healthy. inputPath: testdata/healthy_raw.yaml diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded.yaml index 0cd337860c670..291e4392f59f8 100644 --- a/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded.yaml +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded.yaml @@ -28,3 +28,5 @@ status: reason: Predictor ingress not created status: "False" type: Ready + modelStatus: + transitionStatus: BlockedByFailedLoad \ No newline at end of file diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_modelmesh.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_modelmesh.yaml new file mode 100644 index 0000000000000..54ac46fa59356 --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_modelmesh.yaml @@ -0,0 +1,16 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'True' + type: PredictorReady + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'True' + type: Ready + modelStatus: + transitionStatus: BlockedByFailedLoad diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_ocp.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_ocp.yaml new file mode 100644 index 0000000000000..d85c755dea51b --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/degraded_ocp.yaml @@ -0,0 +1,42 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T23:03:45Z' + reason: PredictorConfigurationReady not ready + severity: Info + status: 'False' + type: LatestDeploymentReady + - lastTransitionTime: '2024-05-30T23:03:45Z' + message: 'Revision "helloworld-predictor-00002" failed with message: .' + reason: RevisionFailed + severity: Info + status: 'False' + type: PredictorConfigurationReady + - lastTransitionTime: '2024-05-30T23:03:45Z' + message: Configuration "helloworld-predictor" does not have any ready Revision. + reason: RevisionMissing + status: 'False' + type: PredictorReady + - lastTransitionTime: '2024-05-30T23:03:45Z' + message: Configuration "helloworld-predictor" does not have any ready Revision. + reason: RevisionMissing + severity: Info + status: 'False' + type: PredictorRouteReady + - lastTransitionTime: '2024-05-30T23:03:45Z' + message: Configuration "helloworld-predictor" does not have any ready Revision. + reason: RevisionMissing + status: 'False' + type: Ready + - lastTransitionTime: '2024-05-30T23:03:45Z' + reason: PredictorRouteReady not ready + severity: Info + status: 'False' + type: RoutesReady + modelStatus: + transitionStatus: BlockedByFailedLoad diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_modelmesh.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_modelmesh.yaml new file mode 100644 index 0000000000000..290171afe2cdd --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_modelmesh.yaml @@ -0,0 +1,16 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'True' + type: PredictorReady + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'True' + type: Ready + modelStatus: + transitionStatus: UpToDate diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_ocp.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_ocp.yaml new file mode 100644 index 0000000000000..9d65c2b379e05 --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/healthy_ocp.yaml @@ -0,0 +1,35 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T22:14:31Z' + status: 'True' + type: IngressReady + - lastTransitionTime: '2024-05-30T22:14:30Z' + severity: Info + status: 'True' + type: LatestDeploymentReady + - lastTransitionTime: '2024-05-30T22:14:30Z' + severity: Info + status: 'True' + type: PredictorConfigurationReady + - lastTransitionTime: '2024-05-30T22:14:31Z' + status: 'True' + type: PredictorReady + - lastTransitionTime: '2024-05-30T22:14:31Z' + severity: Info + status: 'True' + type: PredictorRouteReady + - lastTransitionTime: '2024-05-30T22:14:31Z' + status: 'True' + type: Ready + - lastTransitionTime: '2024-05-30T22:14:31Z' + severity: Info + status: 'True' + type: RoutesReady + modelStatus: + transitionStatus: UpToDate diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_modelmesh.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_modelmesh.yaml new file mode 100644 index 0000000000000..1edb429504e33 --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_modelmesh.yaml @@ -0,0 +1,16 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'False' + type: PredictorReady + - lastTransitionTime: '2024-05-30T22:43:16Z' + status: 'False' + type: Ready + modelStatus: + transitionStatus: InProgress diff --git a/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_ocp.yaml b/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_ocp.yaml new file mode 100644 index 0000000000000..aa476e80cebb4 --- /dev/null +++ b/resource_customizations/serving.kserve.io/InferenceService/testdata/progressing_ocp.yaml @@ -0,0 +1,40 @@ +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: helloworld + namespace: default +spec: {} +status: + conditions: + - lastTransitionTime: '2024-05-30T22:29:46Z' + reason: PredictorConfigurationReady not ready + severity: Info + status: Unknown + type: LatestDeploymentReady + - lastTransitionTime: '2024-05-30T22:29:46Z' + severity: Info + status: Unknown + type: PredictorConfigurationReady + - lastTransitionTime: '2024-05-30T22:29:46Z' + message: Configuration "helloworld-predictor" is waiting for a Revision to become ready. + reason: RevisionMissing + status: Unknown + type: PredictorReady + - lastTransitionTime: '2024-05-30T22:29:46Z' + message: Configuration "helloworld-predictor" is waiting for a Revision to become ready. + reason: RevisionMissing + severity: Info + status: Unknown + type: PredictorRouteReady + - lastTransitionTime: '2024-05-30T22:29:46Z' + message: Configuration "helloworld-predictor" is waiting for a Revision to become ready. + reason: RevisionMissing + status: Unknown + type: Ready + - lastTransitionTime: '2024-05-30T22:29:46Z' + reason: PredictorRouteReady not ready + severity: Info + status: Unknown + type: RoutesReady + modelStatus: + transitionStatus: InProgress diff --git a/resource_customizations/solr.apache.org/SolrCloud/health.lua b/resource_customizations/solr.apache.org/SolrCloud/health.lua new file mode 100644 index 0000000000000..65b90e856f0d7 --- /dev/null +++ b/resource_customizations/solr.apache.org/SolrCloud/health.lua @@ -0,0 +1,24 @@ +-- There is no value in the manifest that can lead to conclude that +-- this resource is in a "Degraded" state. Update this, if in the future +-- this possibility arises. + +if obj.status == nil or obj.status.solrNodes == nil then + return { + status = "Progressing", + message = "Waiting for solr to exist", + } +end + +for _, solrNode in ipairs(obj.status.solrNodes) do + if not solrNode.ready then + return { + status = "Progressing", + message = "Not all replicas are ready", + } + end +end + +return { + status = "Healthy", + message = "Solr is ready", +} \ No newline at end of file diff --git a/resource_customizations/solr.apache.org/SolrCloud/health_test.yaml b/resource_customizations/solr.apache.org/SolrCloud/health_test.yaml new file mode 100644 index 0000000000000..cbe5e56b36631 --- /dev/null +++ b/resource_customizations/solr.apache.org/SolrCloud/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for solr to exist" + inputPath: testdata/provisioning.yaml +- healthStatus: + status: Progressing + message: "Not all replicas are ready" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Solr is ready" + inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/solr.apache.org/SolrCloud/testdata/healthy.yaml b/resource_customizations/solr.apache.org/SolrCloud/testdata/healthy.yaml new file mode 100644 index 0000000000000..229ec17d5047c --- /dev/null +++ b/resource_customizations/solr.apache.org/SolrCloud/testdata/healthy.yaml @@ -0,0 +1,118 @@ +apiVersion: solr.apache.org/v1beta1 +kind: SolrCloud +metadata: + annotations: + argocd.argoproj.io/tracking-id: foobar-solr:solr.apache.org/SolrCloud:foo/solr + creationTimestamp: '2024-10-07T09:30:03Z' + finalizers: + - storage.finalizers.solr.apache.org + generation: 2 + labels: + app.kubernetes.io/instance: foobar-solr + app.kubernetes.io/name: solr + app.kubernetes.io/version: 8.11.1 + helm.sh/chart: solr-0.8.1 + name: solr + namespace: foo + resourceVersion: '339148' + uid: 42f073e1-bf7c-4d2f-923a-66886898e6a2 +spec: + availability: + podDisruptionBudget: + enabled: true + method: ClusterWide + busyBoxImage: + repository: library/busybox + tag: 1.28.0-glibc + customSolrKubeOptions: + podOptions: + defaultInitContainerResources: {} + nodeSelector: + node-role.kubernetes.io/worker: '' + podSecurityContext: + runAsGroup: 8983 + runAsNonRoot: true + runAsUser: 8983 + seccompProfile: + type: RuntimeDefault + resources: {} + serviceAccountName: solr-sa + startupProbe: + periodSeconds: 10 + timeoutSeconds: 30 + dataStorage: + persistent: + pvcTemplate: + metadata: + annotations: + foobar: solr-data + labels: + foobar: solr-data + name: solr-data + spec: + resources: + requests: + storage: 20Gi + reclaimPolicy: Delete + replicas: 1 + scaling: + populatePodsOnScaleUp: true + vacatePodsOnScaleDown: true + solrAddressability: + commonServicePort: 80 + podPort: 8983 + solrImage: + repository: solr + tag: '8.11' + solrJavaMem: '-Xms1g -Xmx2g' + solrLogLevel: DEBUG + solrOpts: '-Dsolr.disable.shardsWhitelist=true' + updateStrategy: + managed: {} + method: Managed + zookeeperRef: + provided: + adminServerService: {} + chroot: / + clientService: {} + config: {} + headlessService: {} + image: + pullPolicy: IfNotPresent + repository: pravega/zookeeper + maxUnavailableReplicas: 1 + persistence: + reclaimPolicy: Delete + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + replicas: 1 + zookeeperPodPolicy: + resources: {} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault +status: + internalCommonAddress: http://solr-solrcloud-common.foo + podSelector: solr-cloud=solr,technology=solr-cloud + readyReplicas: 1 + replicas: 1 + solrNodes: + - internalAddress: http://solr-solrcloud-0.solr-solrcloud-headless.foo:8983 + name: solr-solrcloud-0 + nodeName: crc-j5m2n-master-0 + ready: true + scheduledForDeletion: false + specUpToDate: true + version: '8.11' + upToDateNodes: 1 + version: '8.11' + zookeeperConnectionInfo: + chroot: / + externalConnectionString: N/A + internalConnectionString: >- + solr-solrcloud-zookeeper-0.solr-solrcloud-zookeeper-headless.foo.svc.cluster.local:2181 diff --git a/resource_customizations/solr.apache.org/SolrCloud/testdata/progressing.yaml b/resource_customizations/solr.apache.org/SolrCloud/testdata/progressing.yaml new file mode 100644 index 0000000000000..e870ea085d782 --- /dev/null +++ b/resource_customizations/solr.apache.org/SolrCloud/testdata/progressing.yaml @@ -0,0 +1,125 @@ +apiVersion: solr.apache.org/v1beta1 +kind: SolrCloud +metadata: + annotations: + argocd.argoproj.io/tracking-id: foobar-solr:solr.apache.org/SolrCloud:foo/solr + creationTimestamp: '2024-10-07T09:30:03Z' + finalizers: + - storage.finalizers.solr.apache.org + generation: 2 + labels: + app.kubernetes.io/instance: foobar-solr + app.kubernetes.io/name: solr + app.kubernetes.io/version: 8.11.1 + helm.sh/chart: solr-0.8.1 + name: solr + namespace: foo + resourceVersion: '339148' + uid: 42f073e1-bf7c-4d2f-923a-66886898e6a2 +spec: + availability: + podDisruptionBudget: + enabled: true + method: ClusterWide + busyBoxImage: + repository: library/busybox + tag: 1.28.0-glibc + customSolrKubeOptions: + podOptions: + defaultInitContainerResources: {} + nodeSelector: + node-role.kubernetes.io/worker: '' + podSecurityContext: + runAsGroup: 8983 + runAsNonRoot: true + runAsUser: 8983 + seccompProfile: + type: RuntimeDefault + resources: {} + serviceAccountName: solr-sa + startupProbe: + periodSeconds: 10 + timeoutSeconds: 30 + dataStorage: + persistent: + pvcTemplate: + metadata: + annotations: + foobar: solr-data + labels: + foobar: solr-data + name: solr-data + spec: + resources: + requests: + storage: 20Gi + reclaimPolicy: Delete + replicas: 2 + scaling: + populatePodsOnScaleUp: true + vacatePodsOnScaleDown: true + solrAddressability: + commonServicePort: 80 + podPort: 8983 + solrImage: + repository: solr + tag: '8.11' + solrJavaMem: '-Xms1g -Xmx2g' + solrLogLevel: DEBUG + solrOpts: '-Dsolr.disable.shardsWhitelist=true' + updateStrategy: + managed: {} + method: Managed + zookeeperRef: + provided: + adminServerService: {} + chroot: / + clientService: {} + config: {} + headlessService: {} + image: + pullPolicy: IfNotPresent + repository: pravega/zookeeper + maxUnavailableReplicas: 1 + persistence: + reclaimPolicy: Delete + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + replicas: 1 + zookeeperPodPolicy: + resources: {} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault +status: + internalCommonAddress: http://solr-solrcloud-common.foo + podSelector: solr-cloud=solr,technology=solr-cloud + readyReplicas: 1 + replicas: 2 + solrNodes: + - internalAddress: http://solr-solrcloud-0.solr-solrcloud-headless.foo:8983 + name: solr-solrcloud-0 + nodeName: crc-j5m2n-master-0 + ready: true + scheduledForDeletion: false + specUpToDate: true + version: '8.11' + - internalAddress: http://solr-solrcloud-1.solr-solrcloud-headless.foo:8983 + name: solr-solrcloud-1 + nodeName: '' + ready: false + scheduledForDeletion: false + specUpToDate: true + version: '' + upToDateNodes: 2 + version: '8.11' + zookeeperConnectionInfo: + chroot: / + externalConnectionString: N/A + internalConnectionString: >- + solr-solrcloud-zookeeper-0.solr-solrcloud-zookeeper-headless.foo.svc.cluster.local:2181 diff --git a/resource_customizations/solr.apache.org/SolrCloud/testdata/provisioning.yaml b/resource_customizations/solr.apache.org/SolrCloud/testdata/provisioning.yaml new file mode 100644 index 0000000000000..d635c71850d97 --- /dev/null +++ b/resource_customizations/solr.apache.org/SolrCloud/testdata/provisioning.yaml @@ -0,0 +1,95 @@ +apiVersion: solr.apache.org/v1beta1 +kind: SolrCloud +metadata: + annotations: + argocd.argoproj.io/tracking-id: foobar-solr:solr.apache.org/SolrCloud:foo/solr + finalizers: + - storage.finalizers.solr.apache.org + labels: + app.kubernetes.io/instance: foobar-solr + app.kubernetes.io/name: solr + app.kubernetes.io/version: 8.11.1 + helm.sh/chart: solr-0.8.1 + name: solr + namespace: foo +spec: + availability: + podDisruptionBudget: + enabled: true + method: ClusterWide + busyBoxImage: + repository: library/busybox + tag: 1.28.0-glibc + customSolrKubeOptions: + podOptions: + defaultInitContainerResources: {} + nodeSelector: + node-role.kubernetes.io/worker: '' + podSecurityContext: + runAsGroup: 8983 + runAsNonRoot: true + runAsUser: 8983 + seccompProfile: + type: RuntimeDefault + resources: {} + serviceAccountName: solr-sa + startupProbe: + periodSeconds: 10 + timeoutSeconds: 30 + dataStorage: + persistent: + pvcTemplate: + metadata: + annotations: + foobar: solr-data + labels: + foobar: solr-data + name: solr-data + spec: + resources: + requests: + storage: 20Gi + reclaimPolicy: Delete + replicas: 1 + scaling: + populatePodsOnScaleUp: true + vacatePodsOnScaleDown: true + solrAddressability: + commonServicePort: 80 + podPort: 8983 + solrImage: + repository: solr + tag: '8.11' + solrJavaMem: '-Xms1g -Xmx2g' + solrLogLevel: DEBUG + solrOpts: '-Dsolr.disable.shardsWhitelist=true' + updateStrategy: + managed: {} + method: Managed + zookeeperRef: + provided: + adminServerService: {} + chroot: / + clientService: {} + config: {} + headlessService: {} + image: + pullPolicy: IfNotPresent + repository: pravega/zookeeper + maxUnavailableReplicas: 1 + persistence: + reclaimPolicy: Delete + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + replicas: 1 + zookeeperPodPolicy: + resources: {} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault +status: \ No newline at end of file diff --git a/server/account/account_test.go b/server/account/account_test.go index 03290ad3692c4..81e0abc0785f4 100644 --- a/server/account/account_test.go +++ b/server/account/account_test.go @@ -63,7 +63,7 @@ func newTestAccountServerExt(ctx context.Context, enforceFn rbac.ClaimsEnforcerF for i := range opts { opts[i](cm, secret) } - kubeclientset := fake.NewSimpleClientset(cm, secret) + kubeclientset := fake.NewClientset(cm, secret) settingsMgr := settings.NewSettingsManager(ctx, kubeclientset, testNamespace) sessionMgr := sessionutil.NewSessionManager(settingsMgr, test.NewFakeProjLister(), "", nil, sessionutil.NewUserStateStorage(nil)) enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) @@ -163,16 +163,14 @@ func TestUpdatePassword_DoesNotHavePermissions(t *testing.T) { }) ctx := adminContext(context.Background()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "anotherUser"}) - require.Error(t, err) - assert.Contains(t, err.Error(), "permission denied") + assert.ErrorContains(t, err, "permission denied") }) t.Run("SSOAccountWithTheSameName", func(t *testing.T) { accountServer, _ := newTestAccountServerExt(context.Background(), enforcer) ctx := ssoAdminContext(context.Background(), time.Now()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword", Name: "admin"}) - require.Error(t, err) - assert.Contains(t, err.Error(), "permission denied") + assert.ErrorContains(t, err, "permission denied") }) } @@ -182,8 +180,7 @@ func TestUpdatePassword_ProjectToken(t *testing.T) { }) ctx := projTokenContext(context.Background()) _, err := accountServer.UpdatePassword(ctx, &account.UpdatePasswordRequest{CurrentPassword: "oldpassword", NewPassword: "newpassword"}) - require.Error(t, err) - assert.Contains(t, err.Error(), "password can only be changed for local users") + assert.ErrorContains(t, err, "password can only be changed for local users") } func TestUpdatePassword_OldSSOToken(t *testing.T) { @@ -291,9 +288,8 @@ func TestCreateToken_UserSpecifiedID(t *testing.T) { require.NoError(t, err) _, err = accountServer.CreateToken(ctx, &account.CreateTokenRequest{Name: "account1", Id: "test"}) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to update account with new token:") - assert.Contains(t, err.Error(), "account already has token with id 'test'") + require.ErrorContains(t, err, "failed to update account with new token:") + assert.ErrorContains(t, err, "account already has token with id 'test'") } func TestDeleteToken_SuccessfullyRemoved(t *testing.T) { diff --git a/server/application/application.go b/server/application/application.go index 9e2c39a2060a9..9fee8369795b1 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -369,7 +369,13 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq if err != nil { return nil, status.Errorf(codes.Internal, "unable to check existing application details (%s): %v", appNs, err) } - equalSpecs := reflect.DeepEqual(existing.Spec, a.Spec) && + + if err := argo.ValidateDestination(ctx, &existing.Spec.Destination, s.db); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "application destination spec for %s is invalid: %s", existing.Name, err.Error()) + } + + equalSpecs := existing.Spec.Destination.Equals(a.Spec.Destination) && + reflect.DeepEqual(existing.Spec, a.Spec) && reflect.DeepEqual(existing.Labels, a.Labels) && reflect.DeepEqual(existing.Annotations, a.Annotations) && reflect.DeepEqual(existing.Finalizers, a.Finalizers) @@ -510,26 +516,32 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan if err != nil { return fmt.Errorf("error getting kustomize settings options: %w", err) } + installationID, err := s.settingsMgr.GetInstallationID() + if err != nil { + return fmt.Errorf("error getting installation ID: %w", err) + } manifestInfo, err := client.GenerateManifest(ctx, &apiclient.ManifestRequest{ - Repo: repo, - Revision: source.TargetRevision, - AppLabelKey: appInstanceLabelKey, - AppName: a.InstanceName(s.ns), - Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &source, - Repos: helmRepos, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - HelmRepoCreds: helmCreds, - HelmOptions: helmOptions, - TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, - HasMultipleSources: a.Spec.HasMultipleSources(), - RefSources: refSources, + Repo: repo, + Revision: source.TargetRevision, + AppLabelKey: appInstanceLabelKey, + AppName: a.InstanceName(s.ns), + Namespace: a.Spec.Destination.Namespace, + ApplicationSource: &source, + Repos: helmRepos, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + HelmRepoCreds: helmCreds, + HelmOptions: helmOptions, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + HasMultipleSources: a.Spec.HasMultipleSources(), + RefSources: refSources, + AnnotationManifestGeneratePaths: a.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), + InstallationID: installationID, }) if err != nil { return fmt.Errorf("error generating manifests: %w", err) @@ -551,7 +563,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return nil, fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - obj, _, err = diff.HideSecretData(obj, nil) + obj, _, err = diff.HideSecretData(obj, nil, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, fmt.Errorf("error hiding secret data: %w", err) } @@ -630,22 +642,23 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get } req := &apiclient.ManifestRequest{ - Repo: repo, - Revision: source.TargetRevision, - AppLabelKey: appInstanceLabelKey, - AppName: a.Name, - Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &source, - Repos: helmRepos, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - HelmRepoCreds: helmCreds, - HelmOptions: helmOptions, - TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: repo, + Revision: source.TargetRevision, + AppLabelKey: appInstanceLabelKey, + AppName: a.Name, + Namespace: a.Spec.Destination.Namespace, + ApplicationSource: &source, + Repos: helmRepos, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + HelmRepoCreds: helmCreds, + HelmOptions: helmOptions, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: a.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), } repoStreamClient, err := client.GenerateManifestWithFiles(stream.Context()) @@ -677,7 +690,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get return fmt.Errorf("error unmarshaling manifest into unstructured: %w", err) } if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - obj, _, err = diff.HideSecretData(obj, nil) + obj, _, err = diff.HideSecretData(obj, nil, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return fmt.Errorf("error hiding secret data: %w", err) } @@ -924,8 +937,8 @@ func (s *Server) updateApp(app *appv1.Application, newApp *appv1.Application, ct for i := 0; i < 10; i++ { app.Spec = newApp.Spec if merge { - app.Labels = collections.MergeStringMaps(app.Labels, newApp.Labels) - app.Annotations = collections.MergeStringMaps(app.Annotations, newApp.Annotations) + app.Labels = collections.Merge(app.Labels, newApp.Labels) + app.Annotations = collections.Merge(app.Annotations, newApp.Annotations) } else { app.Labels = newApp.Labels app.Annotations = newApp.Annotations @@ -1222,6 +1235,18 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica if app.GetName() == "" { return fmt.Errorf("resource name may not be empty") } + + // ensure sources names are unique + if app.Spec.HasMultipleSources() { + sourceNames := make(map[string]bool) + for _, source := range app.Spec.Sources { + if len(source.Name) > 0 && sourceNames[source.Name] { + return fmt.Errorf("application %s has duplicate source name: %s", app.Name, source.Name) + } + sourceNames[source.Name] = true + } + } + appNs := s.appNamespaceOrDefault(app.Namespace) currApp, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Get(ctx, app.Name, metav1.GetOptions{}) if err != nil { @@ -1282,7 +1307,11 @@ func (s *Server) getApplicationClusterConfig(ctx context.Context, a *appv1.Appli if err != nil { return nil, fmt.Errorf("error getting cluster: %w", err) } - config := clst.RESTConfig() + config, err := clst.RESTConfig() + if err != nil { + return nil, fmt.Errorf("error getting cluster REST config: %w", err) + } + return config, err } @@ -1362,7 +1391,7 @@ func (s *Server) GetResource(ctx context.Context, q *application.ApplicationReso if err != nil { return nil, fmt.Errorf("error getting resource: %w", err) } - obj, err = replaceSecretValues(obj) + obj, err = s.replaceSecretValues(obj) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } @@ -1374,9 +1403,9 @@ func (s *Server) GetResource(ctx context.Context, q *application.ApplicationReso return &application.ApplicationResourceResponse{Manifest: &manifest}, nil } -func replaceSecretValues(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { +func (s *Server) replaceSecretValues(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { if obj.GetKind() == kube.SecretKind && obj.GroupVersionKind().Group == "" { - _, obj, err := diff.HideSecretData(nil, obj) + _, obj, err := diff.HideSecretData(nil, obj, s.settingsMgr.GetSensitiveAnnotations()) if err != nil { return nil, err } @@ -1413,7 +1442,7 @@ func (s *Server) PatchResource(ctx context.Context, q *application.ApplicationRe if manifest == nil { return nil, fmt.Errorf("failed to patch resource: manifest was nil") } - manifest, err = replaceSecretValues(manifest) + manifest, err = s.replaceSecretValues(manifest) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } @@ -1887,7 +1916,11 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR s.inferResourcesStatusHealth(a) - if !proj.Spec.SyncWindows.Matches(a).CanSync(true) { + canSync, err := proj.Spec.SyncWindows.Matches(a).CanSync(true) + if err != nil { + return a, status.Errorf(codes.PermissionDenied, "cannot sync: invalid sync window: %v", err) + } + if !canSync { return a, status.Errorf(codes.PermissionDenied, "cannot sync: blocked by sync window") } @@ -2169,7 +2202,7 @@ func (s *Server) ListResourceLinks(ctx context.Context, req *application.Applica return nil, fmt.Errorf("failed to read application deep links from configmap: %w", err) } - obj, err = replaceSecretValues(obj) + obj, err = s.replaceSecretValues(obj) if err != nil { return nil, fmt.Errorf("error replacing secret values: %w", err) } @@ -2202,7 +2235,7 @@ func getAmbiguousRevision(app *appv1.Application, syncReq *application.Applicati ambiguousRevision := "" if app.Spec.HasMultipleSources() { for i, pos := range syncReq.SourcePositions { - if pos == int64(sourceIndex) { + if pos == int64(sourceIndex+1) { ambiguousRevision = syncReq.Revisions[i] } } @@ -2604,10 +2637,17 @@ func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.A } windows := proj.Spec.SyncWindows.Matches(a) - sync := windows.CanSync(true) + sync, err := windows.CanSync(true) + if err != nil { + return nil, fmt.Errorf("invalid sync windows: %w", err) + } + activeWindows, err := windows.Active() + if err != nil { + return nil, fmt.Errorf("invalid sync windows: %w", err) + } res := &application.ApplicationSyncWindowsResponse{ - ActiveWindows: convertSyncWindows(windows.Active()), + ActiveWindows: convertSyncWindows(activeWindows), AssignedWindows: convertSyncWindows(windows), CanSync: &sync, } diff --git a/server/application/application_test.go b/server/application/application_test.go index c182829fa19bd..a011014e32ed1 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -109,7 +109,7 @@ func fakeResolveRevisionResponseHelm() *apiclient.ResolveRevisionResponse { func fakeRepoServerClient(isHelm bool) *mocks.RepoServerServiceClient { mockRepoServiceClient := mocks.RepoServerServiceClient{} - mockRepoServiceClient.On("ListApps", mock.Anything, mock.Anything).Return(fakeAppList(), nil) + mockRepoServiceClient.On("GetProcessableApps", mock.Anything, mock.Anything).Return(fakeAppList(), nil) mockRepoServiceClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(&apiclient.ManifestResponse{}, nil) mockRepoServiceClient.On("GetAppDetails", mock.Anything, mock.Anything).Return(&apiclient.RepoAppDetailsResponse{}, nil) mockRepoServiceClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) @@ -131,15 +131,17 @@ func fakeRepoServerClient(isHelm bool) *mocks.RepoServerServiceClient { // return an ApplicationServiceServer which returns fake data func newTestAppServer(t *testing.T, objects ...runtime.Object) *Server { + t.Helper() f := func(enf *rbac.Enforcer) { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") } - return newTestAppServerWithEnforcerConfigure(f, t, map[string]string{}, objects...) + return newTestAppServerWithEnforcerConfigure(t, f, map[string]string{}, objects...) } -func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, additionalConfig map[string]string, objects ...runtime.Object) *Server { - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ +func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), additionalConfig map[string]string, objects ...runtime.Object) *Server { + t.Helper() + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -240,7 +242,7 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, oldVersion = 0 } clonedApp := app.DeepCopy() - clonedApp.ResourceVersion = fmt.Sprintf("%d", oldVersion+1) + clonedApp.ResourceVersion = strconv.Itoa(oldVersion + 1) events <- &appsv1.ApplicationWatchEvent{Type: watch.Added, Application: *clonedApp} } } @@ -315,15 +317,17 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, // return an ApplicationServiceServer which returns fake data func newTestAppServerWithBenchmark(b *testing.B, objects ...runtime.Object) *Server { + b.Helper() f := func(enf *rbac.Enforcer) { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") } - return newTestAppServerWithEnforcerConfigureWithBenchmark(f, b, objects...) + return newTestAppServerWithEnforcerConfigureWithBenchmark(b, f, objects...) } -func newTestAppServerWithEnforcerConfigureWithBenchmark(f func(*rbac.Enforcer), b *testing.B, objects ...runtime.Object) *Server { - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ +func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rbac.Enforcer), objects ...runtime.Object) *Server { + b.Helper() + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -421,7 +425,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(f func(*rbac.Enforcer), oldVersion = 0 } clonedApp := app.DeepCopy() - clonedApp.ResourceVersion = fmt.Sprintf("%d", oldVersion+1) + clonedApp.ResourceVersion = strconv.Itoa(oldVersion + 1) events <- &appsv1.ApplicationWatchEvent{Type: watch.Added, Application: *clonedApp} } } @@ -792,7 +796,7 @@ func TestNoAppEnumeration(t *testing.T) { } }) testDeployment := kube.MustToUnstructured(&deployment) - appServer := newTestAppServerWithEnforcerConfigure(f, t, map[string]string{}, testApp, testHelmApp, testAppMulti, testDeployment) + appServer := newTestAppServerWithEnforcerConfigure(t, f, map[string]string{}, testApp, testHelmApp, testAppMulti, testDeployment) noRoleCtx := context.Background() // nolint:staticcheck @@ -804,35 +808,35 @@ func TestNoAppEnumeration(t *testing.T) { require.NoError(t, err) // nolint:staticcheck _, err = appServer.Get(noRoleCtx, &application.ApplicationQuery{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") // nolint:staticcheck _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") // nolint:staticcheck _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: ptr.To("doest-not-exist"), Project: []string{"test"}}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetManifests", func(t *testing.T) { _, err := appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetManifests(noRoleCtx, &application.ApplicationManifestQuery{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceEvents", func(t *testing.T) { _, err := appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceEvents(noRoleCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("UpdateSpec", func(t *testing.T) { @@ -845,39 +849,39 @@ func TestNoAppEnumeration(t *testing.T) { Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Spec: &appsv1.ApplicationSpec{ Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), Spec: &appsv1.ApplicationSpec{ Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Patch", func(t *testing.T) { _, err := appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`)}) require.NoError(t, err) _, err = appServer.Patch(noRoleCtx, &application.ApplicationPatchRequest{Name: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/source/path", "value": "foo"}]`)}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetResource", func(t *testing.T) { _, err := appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetResource(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("PatchResource", func(t *testing.T) { @@ -886,33 +890,33 @@ func TestNoAppEnumeration(t *testing.T) { // The best we can do is to confirm we get past the permission check. assert.NotEqual(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(noRoleCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Patch: ptr.To(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("DeleteResource", func(t *testing.T) { _, err := appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.DeleteResource(noRoleCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("doest-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ResourceTree", func(t *testing.T) { _, err := appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ResourceTree(noRoleCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RevisionMetadata", func(t *testing.T) { @@ -921,44 +925,44 @@ func TestNoAppEnumeration(t *testing.T) { _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-multi"), SourceIndex: ptr.To(int32(0)), VersionId: ptr.To(int32(1))}) require.NoError(t, err) _, err = appServer.RevisionMetadata(noRoleCtx, &application.RevisionMetadataQuery{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RevisionChartDetails", func(t *testing.T) { _, err := appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-helm")}) require.NoError(t, err) _, err = appServer.RevisionChartDetails(noRoleCtx, &application.RevisionMetadataQuery{Name: ptr.To("test-helm")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ManagedResources", func(t *testing.T) { _, err := appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ManagedResources(noRoleCtx, &application.ResourcesQuery{ApplicationName: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Sync", func(t *testing.T) { _, err := appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.Sync(noRoleCtx, &application.ApplicationSyncRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("TerminateOperation", func(t *testing.T) { @@ -968,11 +972,11 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.TerminateOperation(noRoleCtx, &application.OperationTerminateRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Rollback", func(t *testing.T) { @@ -982,103 +986,103 @@ func TestNoAppEnumeration(t *testing.T) { _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("test-multi"), Id: ptr.To(int64(1))}) require.NoError(t, err) _, err = appServer.Rollback(noRoleCtx, &application.ApplicationRollbackRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceActions", func(t *testing.T) { _, err := appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceActions(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(noRoleCtx, &application.ApplicationResourceRequest{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RunResourceAction", func(t *testing.T) { _, err := appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Action: ptr.To("restart")}) require.NoError(t, err) _, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(noRoleCtx, &application.ResourceActionRunRequest{Group: ptr.To("argoproj.io"), Kind: ptr.To("Application"), Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetApplicationSyncWindows", func(t *testing.T) { _, err := appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.GetApplicationSyncWindows(noRoleCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetManifestsWithFiles", func(t *testing.T) { err := appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "test"}) require.NoError(t, err) err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: noRoleCtx, appName: "test"}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist"}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist", project: "test"}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("WatchResourceTree", func(t *testing.T) { err := appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("test")}, &TestResourceTreeServer{ctx: adminCtx}) require.NoError(t, err) err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("test")}, &TestResourceTreeServer{ctx: noRoleCtx}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("does-not-exist")}, &TestResourceTreeServer{ctx: adminCtx}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: ptr.To("does-not-exist"), Project: ptr.To("test")}, &TestResourceTreeServer{ctx: adminCtx}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("PodLogs", func(t *testing.T) { err := appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("test")}, &TestPodLogsServer{ctx: adminCtx}) require.NoError(t, err) err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("test")}, &TestPodLogsServer{ctx: noRoleCtx}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("does-not-exist")}, &TestPodLogsServer{ctx: adminCtx}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: ptr.To("does-not-exist"), Project: ptr.To("test")}, &TestPodLogsServer{ctx: adminCtx}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListLinks", func(t *testing.T) { _, err := appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListLinks(noRoleCtx, &application.ListAppLinksRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("does-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: ptr.To("does-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceLinks", func(t *testing.T) { _, err := appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) require.NoError(t, err) _, err = appServer.ListResourceLinks(noRoleCtx, &application.ApplicationResourceRequest{Name: ptr.To("test"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("does-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: ptr.To("does-not-exist"), ResourceName: ptr.To("test"), Group: ptr.To("apps"), Kind: ptr.To("Deployment"), Namespace: ptr.To("test"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) // Do this last so other stuff doesn't fail. @@ -1086,16 +1090,17 @@ func TestNoAppEnumeration(t *testing.T) { _, err := appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("test")}) require.NoError(t, err) _, err = appServer.Delete(noRoleCtx, &application.ApplicationDeleteRequest{Name: ptr.To("test")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("doest-not-exist")}) - assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + require.EqualError(t, err, permissionDeniedErr.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: ptr.To("doest-not-exist"), Project: ptr.To("test")}) - assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") + assert.EqualError(t, err, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", "when the request specifies a project, we can return the standard k8s error message") }) } // setSyncRunningOperationState simulates starting a sync operation on the given app. func setSyncRunningOperationState(t *testing.T, appServer *Server) { + t.Helper() appIf := appServer.appclientset.ArgoprojV1alpha1().Applications("default") app, err := appIf.Get(context.Background(), "test", metav1.GetOptions{}) require.NoError(t, err) @@ -1107,6 +1112,7 @@ func setSyncRunningOperationState(t *testing.T, appServer *Server) { // unsetSyncRunningOperationState simulates finishing a sync operation on the given app. func unsetSyncRunningOperationState(t *testing.T, appServer *Server) { + t.Helper() appIf := appServer.appclientset.ArgoprojV1alpha1().Applications("default") app, err := appIf.Get(context.Background(), "test", metav1.GetOptions{}) require.NoError(t, err) @@ -1153,6 +1159,7 @@ func TestListAppsInDefaultNSWithLabels(t *testing.T) { } func testListAppsWithLabels(t *testing.T, appQuery application.ApplicationQuery, appServer *Server) { + t.Helper() validTests := []struct { testName string label string @@ -1334,7 +1341,7 @@ g, group-49, role:test3 ` _ = enf.SetUserPolicy(policy) } - appServer := newTestAppServerWithEnforcerConfigure(f, t, map[string]string{}, objects...) + appServer := newTestAppServerWithEnforcerConfigure(t, f, map[string]string{}, objects...) res, err := appServer.List(ctx, &application.ApplicationQuery{}) @@ -1662,7 +1669,7 @@ func TestDeleteResourcesRBAC(t *testing.T) { p, test-user, applications, delete, default/test-app, allow `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, expectedErrorWhenDeleteAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) t.Run("delete with application permission but deny subresource", func(t *testing.T) { @@ -1671,7 +1678,7 @@ p, test-user, applications, delete, default/test-app, allow p, test-user, applications, delete/*, default/test-app, deny `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, expectedErrorWhenDeleteAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) t.Run("delete with subresource", func(t *testing.T) { @@ -1679,7 +1686,7 @@ p, test-user, applications, delete/*, default/test-app, deny p, test-user, applications, delete/*, default/test-app, allow `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, expectedErrorWhenDeleteAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) t.Run("delete with subresource but deny applications", func(t *testing.T) { @@ -1688,7 +1695,7 @@ p, test-user, applications, delete, default/test-app, deny p, test-user, applications, delete/*, default/test-app, allow `) _, err := appServer.DeleteResource(ctx, &req) - assert.Equal(t, expectedErrorWhenDeleteAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenDeleteAllowed) }) t.Run("delete with specific subresource denied", func(t *testing.T) { @@ -1725,7 +1732,7 @@ func TestPatchResourcesRBAC(t *testing.T) { p, test-user, applications, update, default/test-app, allow `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, expectedErrorWhenUpdateAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) t.Run("patch with application permission but deny subresource", func(t *testing.T) { @@ -1734,7 +1741,7 @@ p, test-user, applications, update, default/test-app, allow p, test-user, applications, update/*, default/test-app, deny `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, expectedErrorWhenUpdateAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) t.Run("patch with subresource", func(t *testing.T) { @@ -1742,7 +1749,7 @@ p, test-user, applications, update/*, default/test-app, deny p, test-user, applications, update/*, default/test-app, allow `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, expectedErrorWhenUpdateAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) t.Run("patch with subresource but deny applications", func(t *testing.T) { @@ -1751,7 +1758,7 @@ p, test-user, applications, update, default/test-app, deny p, test-user, applications, update/*, default/test-app, allow `) _, err := appServer.PatchResource(ctx, &req) - assert.Equal(t, expectedErrorWhenUpdateAllowed, err.Error()) + assert.EqualError(t, err, expectedErrorWhenUpdateAllowed) }) t.Run("patch with specific subresource denied", func(t *testing.T) { @@ -2007,7 +2014,7 @@ func TestServer_GetApplicationSyncWindowsState(t *testing.T) { appServer := newTestAppServer(t, testApp) active, err := appServer.GetApplicationSyncWindows(context.Background(), &application.ApplicationSyncWindowsQuery{Name: &testApp.Name}) - assert.Contains(t, err.Error(), "not exist") + require.ErrorContains(t, err, "not exist") assert.Nil(t, active) }) } @@ -2107,7 +2114,7 @@ func TestSplitStatusPatch(t *testing.T) { otherFields := `{"operation":{"eee":"fff"},"spec":{"aaa":"bbb"},"status":{"ccc":"ddd"}}` nonStatus, status, err := splitStatusPatch([]byte(otherFields)) require.NoError(t, err) - assert.Equal(t, `{"operation":{"eee":"fff"},"spec":{"aaa":"bbb"}}`, string(nonStatus)) + assert.JSONEq(t, `{"operation":{"eee":"fff"},"spec":{"aaa":"bbb"}}`, string(nonStatus)) assert.Equal(t, statusPatch, string(status)) } } @@ -2198,7 +2205,7 @@ func TestMaxPodLogsRender(t *testing.T) { require.Error(t, err) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) - assert.Equal(t, "rpc error: code = InvalidArgument desc = max pods to view logs are reached. Please provide more granular query", err.Error()) + assert.EqualError(t, err, "rpc error: code = InvalidArgument desc = max pods to view logs are reached. Please provide more granular query") }) // Case: number of pods to view logs is less than customMaxPodLogsToRender @@ -2222,12 +2229,13 @@ func TestMaxPodLogsRender(t *testing.T) { require.Error(t, err) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) - assert.Equal(t, "rpc error: code = InvalidArgument desc = max pods to view logs are reached. Please provide more granular query", err.Error()) + assert.EqualError(t, err, "rpc error: code = InvalidArgument desc = max pods to view logs are reached. Please provide more granular query") }) } // createAppServerWithMaxLodLogs creates a new app server with given number of pods and resources func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRender ...int64) (*Server, context.Context) { + t.Helper() runtimeObjects := make([]runtime.Object, podNumber+1) resources := make([]appsv1.ResourceStatus, podNumber) @@ -2269,7 +2277,7 @@ func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRend enf.SetDefaultRole("role:admin") } formatInt := strconv.FormatInt(maxPodLogsToRender[0], 10) - appServer := newTestAppServerWithEnforcerConfigure(f, t, map[string]string{"server.maxPodLogsToRender": formatInt}, runtimeObjects...) + appServer := newTestAppServerWithEnforcerConfigure(t, f, map[string]string{"server.maxPodLogsToRender": formatInt}, runtimeObjects...) return appServer, adminCtx } else { appServer := newTestAppServer(t, runtimeObjects...) @@ -2279,6 +2287,7 @@ func createAppServerWithMaxLodLogs(t *testing.T, podNumber int, maxPodLogsToRend // refreshAnnotationRemover runs an infinite loop until it detects and removes refresh annotation or given context is done func refreshAnnotationRemover(t *testing.T, ctx context.Context, patched *int32, appServer *Server, appName string, ch chan string) { + t.Helper() for ctx.Err() == nil { aName, appNs := argo.ParseFromQualifiedName(appName, appServer.ns) a, err := appServer.appLister.Applications(appNs).Get(aName) @@ -2501,7 +2510,7 @@ func TestRunNewStyleResourceAction(t *testing.T) { Kind: &kind, }) - assert.Contains(t, runErr.Error(), "is not permitted to manage") + require.ErrorContains(t, runErr, "is not permitted to manage") assert.Nil(t, appResponse) }) @@ -2718,7 +2727,6 @@ func TestAppNamespaceRestrictions(t *testing.T) { Name: ptr.To("test-app"), AppNamespace: ptr.To("argocd-1"), }) - require.Error(t, err) require.ErrorContains(t, err, "permission denied") require.Nil(t, app) }) @@ -2938,23 +2946,19 @@ func TestGetAmbiguousRevision_MultiSource(t *testing.T) { }, } syncReq := &application.ApplicationSyncRequest{ - SourcePositions: []int64{0, 1}, + SourcePositions: []int64{1, 2}, Revisions: []string{"rev1", "rev2"}, } sourceIndex := 0 expected := "rev1" result := getAmbiguousRevision(app, syncReq, sourceIndex) - if result != expected { - t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result) - } + assert.Equalf(t, expected, result, "Expected ambiguous revision to be %s, but got %s", expected, result) sourceIndex = 1 expected = "rev2" result = getAmbiguousRevision(app, syncReq, sourceIndex) - if result != expected { - t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result) - } + assert.Equal(t, expected, result, "Expected ambiguous revision to be %s, but got %s", expected, result) // Test when app.Spec.HasMultipleSources() is false app.Spec = appv1.ApplicationSpec{ @@ -2968,9 +2972,7 @@ func TestGetAmbiguousRevision_MultiSource(t *testing.T) { } expected = "revision3" result = getAmbiguousRevision(app, syncReq, sourceIndex) - if result != expected { - t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result) - } + assert.Equal(t, expected, result, "Expected ambiguous revision to be %s, but got %s", expected, result) } func TestGetAmbiguousRevision_SingleSource(t *testing.T) { @@ -2989,9 +2991,7 @@ func TestGetAmbiguousRevision_SingleSource(t *testing.T) { sourceIndex := 1 expected := "rev1" result := getAmbiguousRevision(app, syncReq, sourceIndex) - if result != expected { - t.Errorf("Expected ambiguous revision to be %s, but got %s", expected, result) - } + assert.Equalf(t, expected, result, "Expected ambiguous revision to be %s, but got %s", expected, result) } func TestServer_ResolveSourceRevisions_MultiSource(t *testing.T) { diff --git a/server/application/logs.go b/server/application/logs.go index 778f04edec66e..b52eef81e2e77 100644 --- a/server/application/logs.go +++ b/server/application/logs.go @@ -120,16 +120,22 @@ func mergeLogStreams(streams []chan logEntry, bufferingDuration time.Duration) c var sentAt time.Time ticker := time.NewTicker(bufferingDuration) + done := make(chan struct{}) go func() { - for range ticker.C { - sentAtLock.Lock() - // waited long enough for logs from each streams, send everything accumulated - if sentAt.Add(bufferingDuration).Before(time.Now()) { - _ = send(true) - sentAt = time.Now() - } + for { + select { + case <-done: + return + case <-ticker.C: + sentAtLock.Lock() + // waited long enough for logs from each streams, send everything accumulated + if sentAt.Add(bufferingDuration).Before(time.Now()) { + _ = send(true) + sentAt = time.Now() + } - sentAtLock.Unlock() + sentAtLock.Unlock() + } } }() @@ -145,6 +151,11 @@ func mergeLogStreams(streams []chan logEntry, bufferingDuration time.Duration) c _ = send(true) ticker.Stop() + // ticker.Stop() does not close the channel, and it does not wait for the channel to be drained. So we need to + // explicitly prevent the gorountine from leaking by closing the channel. We also need to prevent the goroutine + // from calling `send` again, because `send` pushes to the `merged` channel which we're about to close. + // This describes the approach nicely: https://stackoverflow.com/questions/17797754/ticker-stop-behaviour-in-golang + done <- struct{}{} close(merged) }() return merged diff --git a/server/application/logs_test.go b/server/application/logs_test.go index 76bd5df134ae9..7a565e37efa79 100644 --- a/server/application/logs_test.go +++ b/server/application/logs_test.go @@ -75,3 +75,33 @@ func TestMergeLogStreams(t *testing.T) { assert.Equal(t, []string{"1", "2", "3", "4"}, lines) } + +func TestMergeLogStreams_RaceCondition(t *testing.T) { + // Test for regression of this issue: https://github.com/argoproj/argo-cd/issues/7006 + for i := 0; i < 5000; i++ { + first := make(chan logEntry) + second := make(chan logEntry) + + go func() { + parseLogsStream("first", io.NopCloser(strings.NewReader(`2021-02-09T00:00:01Z 1`)), first) + time.Sleep(time.Duration(i%3) * time.Millisecond) + close(first) + }() + + go func() { + parseLogsStream("second", io.NopCloser(strings.NewReader(`2021-02-09T00:00:02Z 2`)), second) + time.Sleep(time.Duration((i+1)%3) * time.Millisecond) + close(second) + }() + + merged := mergeLogStreams([]chan logEntry{first, second}, 1*time.Millisecond) + + // Drain the channel + for range merged { + } + + // This test intentionally doesn't test the order of the output. Under these intense conditions, the test would + // fail often due to out of order entries. This test is only meant to reproduce a race between a channel writer + // and channel closer. + } +} diff --git a/server/application/terminal.go b/server/application/terminal.go index e6ddc6d832df3..46884ce2ffa5e 100644 --- a/server/application/terminal.go +++ b/server/application/terminal.go @@ -70,7 +70,11 @@ func (s *terminalHandler) getApplicationClusterRawConfig(ctx context.Context, a if err != nil { return nil, err } - return clst.RawRestConfig(), nil + rawConfig, err := clst.RawRestConfig() + if err != nil { + return nil, err + } + return rawConfig, nil } type GetSettingsFunc func() (*settings.ArgoCDSettings, error) diff --git a/server/application/terminal_test.go b/server/application/terminal_test.go index abad3ea3c2418..fb55dd478f4d9 100644 --- a/server/application/terminal_test.go +++ b/server/application/terminal_test.go @@ -74,9 +74,7 @@ func TestPodExists(t *testing.T) { } { t.Run(tcase.name, func(t *testing.T) { result := podExists(tcase.treeNodes, tcase.podName, tcase.namespace) - if result != tcase.expectedResult { - t.Errorf("Expected result %v, but got %v", tcase.expectedResult, result) - } + assert.Equalf(t, tcase.expectedResult, result, "Expected result %v, but got %v", tcase.expectedResult, result) }) } } @@ -110,9 +108,7 @@ func TestIsValidPodName(t *testing.T) { } { t.Run(tcase.name, func(t *testing.T) { result := argo.IsValidPodName(tcase.resourceName) - if result != tcase.expectedResult { - t.Errorf("Expected result %v, but got %v", tcase.expectedResult, result) - } + assert.Equalf(t, tcase.expectedResult, result, "Expected result %v, but got %v", tcase.expectedResult, result) }) } } @@ -141,9 +137,7 @@ func TestIsValidNamespaceName(t *testing.T) { } { t.Run(tcase.name, func(t *testing.T) { result := argo.IsValidNamespaceName(tcase.resourceName) - if result != tcase.expectedResult { - t.Errorf("Expected result %v, but got %v", tcase.expectedResult, result) - } + assert.Equalf(t, tcase.expectedResult, result, "Expected result %v, but got %v", tcase.expectedResult, result) }) } } @@ -172,9 +166,7 @@ func TestIsValidContainerNameName(t *testing.T) { } { t.Run(tcase.name, func(t *testing.T) { result := argo.IsValidContainerName(tcase.resourceName) - if result != tcase.expectedResult { - t.Errorf("Expected result %v, but got %v", tcase.expectedResult, result) - } + assert.Equalf(t, tcase.expectedResult, result, "Expected result %v, but got %v", tcase.expectedResult, result) }) } } diff --git a/server/application/websocket_test.go b/server/application/websocket_test.go index 6a47ee1e8ed8e..1683ad1889a6b 100644 --- a/server/application/websocket_test.go +++ b/server/application/websocket_test.go @@ -34,7 +34,7 @@ func newTestTerminalSession(w http.ResponseWriter, r *http.Request) terminalSess func newEnforcer() *rbac.Enforcer { additionalConfig := make(map[string]string, 0) - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -86,6 +86,7 @@ func TestReconnect(t *testing.T) { } func testServerConnection(t *testing.T, testFunc func(w http.ResponseWriter, r *http.Request), expectPermissionDenied bool) { + t.Helper() s := httptest.NewServer(http.HandlerFunc(testFunc)) defer s.Close() @@ -159,7 +160,7 @@ func TestValidateWithoutPermissions(t *testing.T) { ts.ctx = context.WithValue(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"test"}}) _, err := ts.validatePermissions([]byte{}) require.Error(t, err) - assert.Equal(t, permissionDeniedErr.Error(), err.Error()) + assert.EqualError(t, err, permissionDeniedErr.Error()) } testServerConnection(t, validate, true) diff --git a/server/applicationset/applicationset.go b/server/applicationset/applicationset.go index 259b59c911321..b5288c71c1509 100644 --- a/server/applicationset/applicationset.go +++ b/server/applicationset/applicationset.go @@ -265,7 +265,7 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre func (s *Server) generateApplicationSetApps(ctx context.Context, logEntry *log.Entry, appset v1alpha1.ApplicationSet, namespace string) ([]v1alpha1.Application, error) { argoCDDB := s.db - scmConfig := generators.NewSCMConfig(s.ScmRootCAPath, s.AllowedScmProviders, s.EnableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB))) + scmConfig := generators.NewSCMConfig(s.ScmRootCAPath, s.AllowedScmProviders, s.EnableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB)), true) getRepository := func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return s.db.GetRepository(ctx, url, project) @@ -300,8 +300,8 @@ func (s *Server) updateAppSet(appset *v1alpha1.ApplicationSet, newAppset *v1alph for i := 0; i < 10; i++ { appset.Spec = newAppset.Spec if merge { - appset.Labels = collections.MergeStringMaps(appset.Labels, newAppset.Labels) - appset.Annotations = collections.MergeStringMaps(appset.Annotations, newAppset.Annotations) + appset.Labels = collections.Merge(appset.Labels, newAppset.Labels) + appset.Annotations = collections.Merge(appset.Annotations, newAppset.Annotations) } else { appset.Labels = newAppset.Labels appset.Annotations = newAppset.Annotations diff --git a/server/applicationset/applicationset_test.go b/server/applicationset/applicationset_test.go index 0b83dfa2c4c90..8f16d415dec13 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -72,7 +72,7 @@ func newTestNamespacedAppSetServer(objects ...runtime.Object) *Server { } func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace string, objects ...runtime.Object) *Server { - kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ + kubeclientset := fake.NewClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -190,6 +190,7 @@ func newTestAppSet(opts ...func(appset *appsv1.ApplicationSet)) *appsv1.Applicat } func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.ApplicationSetListQuery, appServer *Server) { + t.Helper() validTests := []struct { testName string label string @@ -357,7 +358,7 @@ func TestCreateAppSetTemplatedProject(t *testing.T) { Applicationset: testAppSet, } _, err := appServer.Create(context.Background(), &createReq) - assert.Equal(t, "error validating ApplicationSets: the Argo CD API does not currently support creating ApplicationSets with templated `project` fields", err.Error()) + assert.EqualError(t, err, "error validating ApplicationSets: the Argo CD API does not currently support creating ApplicationSets with templated `project` fields") } func TestCreateAppSetWrongNamespace(t *testing.T) { @@ -369,7 +370,7 @@ func TestCreateAppSetWrongNamespace(t *testing.T) { } _, err := appServer.Create(context.Background(), &createReq) - assert.Equal(t, "namespace 'NOT-ALLOWED' is not permitted", err.Error()) + assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") } func TestCreateAppSetDryRun(t *testing.T) { @@ -465,7 +466,7 @@ func TestGetAppSet(t *testing.T) { appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1", AppsetNamespace: "NOT-ALLOWED"} _, err := appSetServer.Get(context.Background(), &appsetQuery) - assert.Equal(t, "namespace 'NOT-ALLOWED' is not permitted", err.Error()) + assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") }) } @@ -635,6 +636,6 @@ func TestResourceTree(t *testing.T) { appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1", AppsetNamespace: "NOT-ALLOWED"} _, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) - assert.Equal(t, "namespace 'NOT-ALLOWED' is not permitted", err.Error()) + assert.EqualError(t, err, "namespace 'NOT-ALLOWED' is not permitted") }) } diff --git a/server/badge/badge_test.go b/server/badge/badge_test.go index 8e1d8819165bf..47ebde8f5aa2a 100644 --- a/server/badge/badge_test.go +++ b/server/badge/badge_test.go @@ -100,7 +100,7 @@ func testProject() *v1alpha1.AppProject { } func TestHandlerFeatureIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app", nil) require.NoError(t, err) @@ -198,7 +198,7 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) { argoCDCm.ObjectMeta.Namespace = tt.namespace argoCDSecret.ObjectMeta.Namespace = tt.namespace - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm, argoCDSecret), tt.namespace) + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm, argoCDSecret), tt.namespace) objects := []runtime.Object{testProject()} for _, v := range tt.testApp { objects = append(objects, v) @@ -209,7 +209,7 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) { require.NoError(t, err) handler.ServeHTTP(rr, req) require.Equal(t, tt.response, rr.Result().StatusCode) - if rr.Result().StatusCode != 400 { + if rr.Result().StatusCode != http.StatusBadRequest { assert.Equal(t, "private, no-store", rr.Header().Get("Cache-Control")) assert.Equal(t, "*", rr.Header().Get("Access-Control-Allow-Origin")) response := rr.Body.String() @@ -225,7 +225,7 @@ func TestHandlerFeatureProjectIsEnabled(t *testing.T) { func TestHandlerNamespacesIsEnabled(t *testing.T) { t.Run("Application in allowed namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=argocd-test", nil) require.NoError(t, err) @@ -246,7 +246,7 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { }) t.Run("Application in disallowed namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube-system", nil) require.NoError(t, err) @@ -263,7 +263,7 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { }) t.Run("Request with illegal namespace", func(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp2()), settingsMgr, "default", []string{"argocd-test"}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&namespace=kube()system", nil) require.NoError(t, err) @@ -276,7 +276,7 @@ func TestHandlerNamespacesIsEnabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{""}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=true", nil) require.NoError(t, err) @@ -297,7 +297,7 @@ func TestHandlerFeatureIsEnabledKeepFullRevisionIsEnabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionIsDisabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=false", nil) require.NoError(t, err) @@ -318,7 +318,7 @@ func TestHandlerFeatureIsEnabledKeepFullRevisionIsDisabled(t *testing.T) { } func TestHandlerFeatureIsEnabledKeepFullRevisionAndWidthIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp3()), settingsMgr, "argocd-test", []string{""}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true&keepFullRevision=true&width=500", nil) require.NoError(t, err) @@ -392,7 +392,7 @@ func createApplicationsWithName(appCombo, projectName []string, namespace string } func TestHandlerFeatureIsEnabledRevisionIsEnabled(t *testing.T) { - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(testApp()), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) @@ -416,7 +416,7 @@ func TestHandlerRevisionIsEnabledNoOperationState(t *testing.T) { app := testApp() app.Status.OperationState = nil - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) @@ -440,7 +440,7 @@ func TestHandlerRevisionIsEnabledShortCommitSHA(t *testing.T) { app := testApp() app.Status.OperationState.SyncResult.Revision = "abc" - settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewSimpleClientset(argoCDCm(), argoCDSecret()), "default") + settingsMgr := settings.NewSettingsManager(context.Background(), fake.NewClientset(argoCDCm(), argoCDSecret()), "default") handler := NewHandler(appclientset.NewSimpleClientset(app), settingsMgr, "default", []string{}) req, err := http.NewRequest(http.MethodGet, "/api/badge?name=test-app&revision=true", nil) require.NoError(t, err) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index c92600448ed75..20ddfcbbfb1e1 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -2,6 +2,7 @@ package cluster import ( "context" + "fmt" "net/url" "time" @@ -53,14 +54,14 @@ func CreateClusterRBACObject(project string, server string) string { func (s *Server) List(ctx context.Context, q *cluster.ClusterQuery) (*appv1.ClusterList, error) { clusterList, err := s.db.ListClusters(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list clusters: %w", err) } filteredItems := clusterList.Items // Filter clusters by id if filteredItems, err = filterClustersById(filteredItems, q.Id); err != nil { - return nil, err + return nil, fmt.Errorf("error filtering clusters by id: %w", err) } // Filter clusters by name @@ -80,7 +81,7 @@ func (s *Server) List(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Clus return nil }) if err != nil { - return nil, err + return nil, fmt.Errorf("error running async cluster responses: %w", err) } cl := *clusterList @@ -102,7 +103,7 @@ func filterClustersById(clusters []appv1.Cluster, id *cluster.ClusterID) ([]appv case "name_escaped": nameUnescaped, err := url.QueryUnescape(id.Value) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to unescape cluster name: %w", err) } items = filterClustersByName(clusters, nameUnescaped) default: @@ -143,12 +144,17 @@ func filterClustersByServer(clusters []appv1.Cluster, server string) []appv1.Clu // Create creates a cluster func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (*appv1.Cluster, error) { if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionCreate, CreateClusterRBACObject(q.Cluster.Project, q.Cluster.Server)); err != nil { - return nil, err + return nil, fmt.Errorf("permission denied while creating cluster: %w", err) } c := q.Cluster - serverVersion, err := s.kubectl.GetServerVersion(c.RESTConfig()) + clusterRESTConfig, err := c.RESTConfig() if err != nil { - return nil, err + return nil, fmt.Errorf("error getting REST config: %w", err) + } + + serverVersion, err := s.kubectl.GetServerVersion(clusterRESTConfig) + if err != nil { + return nil, fmt.Errorf("error getting server version: %w", err) } clust, err := s.db.CreateCluster(ctx, c) @@ -168,7 +174,7 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("cluster", existing, c)) } } else { - return nil, err + return nil, fmt.Errorf("error creating cluster: %w", err) } } @@ -180,7 +186,7 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* }, }) if err != nil { - return nil, err + return nil, fmt.Errorf("error setting cluster info in cache: %w", err) } return s.toAPIResponse(clust), err } @@ -189,7 +195,7 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* func (s *Server) Get(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Cluster, error) { c, err := s.getClusterAndVerifyAccess(ctx, q, rbacpolicy.ActionGet) if err != nil { - return nil, err + return nil, fmt.Errorf("error verifying access to update cluster: %w", err) } return s.toAPIResponse(c), nil @@ -206,7 +212,7 @@ func (s *Server) getClusterWith403IfNotExist(ctx context.Context, q *cluster.Clu func (s *Server) getClusterAndVerifyAccess(ctx context.Context, q *cluster.ClusterQuery, action string) (*appv1.Cluster, error) { c, err := s.getClusterWith403IfNotExist(ctx, q) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get cluster with permissions check: %w", err) } // verify that user can do the specified action inside project where cluster is located @@ -227,7 +233,7 @@ func (s *Server) getCluster(ctx context.Context, q *cluster.ClusterQuery) (*appv } else if q.Id.Type == "name_escaped" { nameUnescaped, err := url.QueryUnescape(q.Id.Value) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to unescape cluster name: %w", err) } q.Name = nameUnescaped } else { @@ -238,7 +244,7 @@ func (s *Server) getCluster(ctx context.Context, q *cluster.ClusterQuery) (*appv if q.Server != "" { c, err := s.db.GetCluster(ctx, q.Server) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get cluster by server: %w", err) } return c, nil } @@ -248,7 +254,7 @@ func (s *Server) getCluster(ctx context.Context, q *cluster.ClusterQuery) (*appv if q.Name != "" { clusterList, err := s.db.ListClusters(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list clusters: %w", err) } for _, c := range clusterList.Items { if c.Name == q.Name { @@ -295,7 +301,7 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (* Id: q.Id, }, rbacpolicy.ActionUpdate) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to verify access for updating cluster: %w", err) } if len(q.UpdatedFields) == 0 || sets.NewString(q.UpdatedFields...).Has("project") { @@ -313,16 +319,20 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (* } q.Cluster = c } + clusterRESTConfig, err := q.Cluster.RESTConfig() + if err != nil { + return nil, fmt.Errorf("failed to get REST config for cluster: %w", err) + } // Test the token we just created before persisting it - serverVersion, err := s.kubectl.GetServerVersion(q.Cluster.RESTConfig()) + serverVersion, err := s.kubectl.GetServerVersion(clusterRESTConfig) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get server version: %w", err) } clust, err := s.db.UpdateCluster(ctx, q.Cluster) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to update cluster in database: %w", err) } err = s.cache.SetClusterInfo(clust.Server, &appv1.ClusterInfo{ ServerVersion: serverVersion, @@ -332,7 +342,7 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (* }, }) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to set cluster info in cache: %w", err) } return s.toAPIResponse(clust), nil } @@ -341,7 +351,7 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (* func (s *Server) Delete(ctx context.Context, q *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { c, err := s.getClusterWith403IfNotExist(ctx, q) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get cluster with permissions check: %w", err) } if q.Name != "" { @@ -352,12 +362,12 @@ func (s *Server) Delete(ctx context.Context, q *cluster.ClusterQuery) (*cluster. } for _, server := range servers { if err := enforceAndDelete(s, ctx, server, c.Project); err != nil { - return nil, err + return nil, fmt.Errorf("failed to enforce and delete cluster server: %w", err) } } } else { if err := enforceAndDelete(s, ctx, q.Server, c.Project); err != nil { - return nil, err + return nil, fmt.Errorf("failed to enforce and delete cluster server: %w", err) } } @@ -379,7 +389,7 @@ func enforceAndDelete(s *Server, ctx context.Context, server, project string) er func (s *Server) RotateAuth(ctx context.Context, q *cluster.ClusterQuery) (*cluster.ClusterResponse, error) { clust, err := s.getClusterWith403IfNotExist(ctx, q) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get cluster with permissions check: %w", err) } var servers []string @@ -406,36 +416,43 @@ func (s *Server) RotateAuth(ctx context.Context, q *cluster.ClusterQuery) (*clus for _, server := range servers { logCtx := log.WithField("cluster", server) logCtx.Info("Rotating auth") - restCfg := clust.RESTConfig() + restCfg, err := clust.RESTConfig() + if err != nil { + return nil, fmt.Errorf("failed to get REST config for cluster: %w", err) + } if restCfg.BearerToken == "" { return nil, status.Errorf(codes.InvalidArgument, "Cluster '%s' does not use bearer token authentication", server) } claims, err := clusterauth.ParseServiceAccountToken(restCfg.BearerToken) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse service account token: %w", err) } kubeclientset, err := kubernetes.NewForConfig(restCfg) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create Kubernetes clientset: %w", err) } newSecret, err := clusterauth.GenerateNewClusterManagerSecret(kubeclientset, claims) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to generate new cluster manager secret: %w", err) } // we are using token auth, make sure we don't store client-cert information clust.Config.KeyData = nil clust.Config.CertData = nil clust.Config.BearerToken = string(newSecret.Data["token"]) + clusterRESTConfig, err := clust.RESTConfig() + if err != nil { + return nil, fmt.Errorf("failed to get REST config for cluster: %w", err) + } // Test the token we just created before persisting it - serverVersion, err := s.kubectl.GetServerVersion(clust.RESTConfig()) + serverVersion, err := s.kubectl.GetServerVersion(clusterRESTConfig) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get server version: %w", err) } _, err = s.db.UpdateCluster(ctx, clust) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to update cluster in database: %w", err) } err = s.cache.SetClusterInfo(clust.Server, &appv1.ClusterInfo{ ServerVersion: serverVersion, @@ -445,11 +462,11 @@ func (s *Server) RotateAuth(ctx context.Context, q *cluster.ClusterQuery) (*clus }, }) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to set cluster info in cache: %w", err) } err = clusterauth.RotateServiceAccountSecrets(kubeclientset, claims, newSecret) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to rotate service account secrets: %w", err) } logCtx.Infof("Rotated auth (old: %s, new: %s)", claims.SecretName, newSecret.Name) } @@ -482,13 +499,13 @@ func (s *Server) toAPIResponse(clust *appv1.Cluster) *appv1.Cluster { func (s *Server) InvalidateCache(ctx context.Context, q *cluster.ClusterQuery) (*appv1.Cluster, error) { cls, err := s.getClusterAndVerifyAccess(ctx, q, rbacpolicy.ActionUpdate) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to verify access for cluster: %w", err) } now := v1.Now() cls.RefreshRequestedAt = &now cls, err = s.db.UpdateCluster(ctx, cls) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to update cluster in database: %w", err) } return s.toAPIResponse(cls), nil } diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 567de3a661901..f5540dd30753d 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -39,6 +39,74 @@ import ( "github.com/argoproj/argo-cd/v2/util/settings" ) +const ( + rootCACert = `-----BEGIN CERTIFICATE----- +MIIC4DCCAcqgAwIBAgIBATALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu +MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIxNTczN1oXDTE2MDExNTIxNTcz +OFowIzEhMB8GA1UEAwwYMTAuMTMuMTI5LjEwNkAxNDIxMzU5MDU4MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunDRXGwsiYWGFDlWH6kjGun+PshDGeZX +xtx9lUnL8pIRWH3wX6f13PO9sktaOWW0T0mlo6k2bMlSLlSZgG9H6og0W6gLS3vq +s4VavZ6DbXIwemZG2vbRwsvR+t4G6Nbwelm6F8RFnA1Fwt428pavmNQ/wgYzo+T1 +1eS+HiN4ACnSoDSx3QRWcgBkB1g6VReofVjx63i0J+w8Q/41L9GUuLqquFxu6ZnH +60vTB55lHgFiDLjA1FkEz2dGvGh/wtnFlRvjaPC54JH2K1mPYAUXTreoeJtLJKX0 +ycoiyB24+zGCniUmgIsmQWRPaOPircexCp1BOeze82BT1LCZNTVaxQIDAQABoyMw +ITAOBgNVHQ8BAf8EBAMCAKQwDwYDVR0TAQH/BAUwAwEB/zALBgkqhkiG9w0BAQsD +ggEBADMxsUuAFlsYDpF4fRCzXXwrhbtj4oQwcHpbu+rnOPHCZupiafzZpDu+rw4x +YGPnCb594bRTQn4pAu3Ac18NbLD5pV3uioAkv8oPkgr8aUhXqiv7KdDiaWm6sbAL +EHiXVBBAFvQws10HMqMoKtO8f1XDNAUkWduakR/U6yMgvOPwS7xl0eUTqyRB6zGb +K55q2dejiFWaFqB/y78txzvz6UlOZKE44g2JAVoJVM6kGaxh33q8/FmrL4kuN3ut +W+MmJCVDvd4eEqPwbp7146ZWTqpIJ8lvA6wuChtqV8lhAPka2hD/LMqY8iXNmfXD +uml0obOEy+ON91k+SWTJ3ggmF/U= +-----END CERTIFICATE-----` + + certData = `-----BEGIN CERTIFICATE----- +MIIC6jCCAdSgAwIBAgIBCzALBgkqhkiG9w0BAQswIzEhMB8GA1UEAwwYMTAuMTMu +MTI5LjEwNkAxNDIxMzU5MDU4MB4XDTE1MDExNTIyMDEzMVoXDTE2MDExNTIyMDEz +MlowGzEZMBcGA1UEAxMQb3BlbnNoaWZ0LWNsaWVudDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKtdhz0+uCLXw5cSYns9rU/XifFSpb/x24WDdrm72S/v +b9BPYsAStiP148buylr1SOuNi8sTAZmlVDDIpIVwMLff+o2rKYDicn9fjbrTxTOj +lI4pHJBH+JU3AJ0tbajupioh70jwFS0oYpwtneg2zcnE2Z4l6mhrj2okrc5Q1/X2 +I2HChtIU4JYTisObtin10QKJX01CLfYXJLa8upWzKZ4/GOcHG+eAV3jXWoXidtjb +1Usw70amoTZ6mIVCkiu1QwCoa8+ycojGfZhvqMsAp1536ZcCul+Na+AbCv4zKS7F +kQQaImVrXdUiFansIoofGlw/JNuoKK6ssVpS5Ic3pgcCAwEAAaM1MDMwDgYDVR0P +AQH/BAQDAgCgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCwYJ +KoZIhvcNAQELA4IBAQCKLREH7bXtXtZ+8vI6cjD7W3QikiArGqbl36bAhhWsJLp/ +p/ndKz39iFNaiZ3GlwIURWOOKx3y3GA0x9m8FR+Llthf0EQ8sUjnwaknWs0Y6DQ3 +jjPFZOpV3KPCFrdMJ3++E3MgwFC/Ih/N2ebFX9EcV9Vcc6oVWMdwT0fsrhu683rq +6GSR/3iVX1G/pmOiuaR0fNUaCyCfYrnI4zHBDgSfnlm3vIvN2lrsR/DQBakNL8DJ +HBgKxMGeUPoneBv+c8DMXIL0EhaFXRlBv9QW45/GiAIOuyFJ0i6hCtGZpJjq4OpQ +BRjCI+izPzFTjsxD4aORE+WOkyWFCGPWKfNejfw0 +-----END CERTIFICATE-----` + + keyData = `-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAq12HPT64ItfDlxJiez2tT9eJ8VKlv/HbhYN2ubvZL+9v0E9i +wBK2I/Xjxu7KWvVI642LyxMBmaVUMMikhXAwt9/6jaspgOJyf1+NutPFM6OUjikc +kEf4lTcAnS1tqO6mKiHvSPAVLShinC2d6DbNycTZniXqaGuPaiStzlDX9fYjYcKG +0hTglhOKw5u2KfXRAolfTUIt9hcktry6lbMpnj8Y5wcb54BXeNdaheJ22NvVSzDv +RqahNnqYhUKSK7VDAKhrz7JyiMZ9mG+oywCnXnfplwK6X41r4BsK/jMpLsWRBBoi +ZWtd1SIVqewiih8aXD8k26gorqyxWlLkhzemBwIDAQABAoIBAD2XYRs3JrGHQUpU +FkdbVKZkvrSY0vAZOqBTLuH0zUv4UATb8487anGkWBjRDLQCgxH+jucPTrztekQK +aW94clo0S3aNtV4YhbSYIHWs1a0It0UdK6ID7CmdWkAj6s0T8W8lQT7C46mWYVLm +5mFnCTHi6aB42jZrqmEpC7sivWwuU0xqj3Ml8kkxQCGmyc9JjmCB4OrFFC8NNt6M +ObvQkUI6Z3nO4phTbpxkE1/9dT0MmPIF7GhHVzJMS+EyyRYUDllZ0wvVSOM3qZT0 +JMUaBerkNwm9foKJ1+dv2nMKZZbJajv7suUDCfU44mVeaEO+4kmTKSGCGjjTBGkr +7L1ySDECgYEA5ElIMhpdBzIivCuBIH8LlUeuzd93pqssO1G2Xg0jHtfM4tz7fyeI +cr90dc8gpli24dkSxzLeg3Tn3wIj/Bu64m2TpZPZEIlukYvgdgArmRIPQVxerYey +OkrfTNkxU1HXsYjLCdGcGXs5lmb+K/kuTcFxaMOs7jZi7La+jEONwf8CgYEAwCs/ +rUOOA0klDsWWisbivOiNPII79c9McZCNBqncCBfMUoiGe8uWDEO4TFHN60vFuVk9 +8PkwpCfvaBUX+ajvbafIfHxsnfk1M04WLGCeqQ/ym5Q4sQoQOcC1b1y9qc/xEWfg +nIUuia0ukYRpl7qQa3tNg+BNFyjypW8zukUAC/kCgYB1/Kojuxx5q5/oQVPrx73k +2bevD+B3c+DYh9MJqSCNwFtUpYIWpggPxoQan4LwdsmO0PKzocb/ilyNFj4i/vII +NToqSc/WjDFpaDIKyuu9oWfhECye45NqLWhb/6VOuu4QA/Nsj7luMhIBehnEAHW+ +GkzTKM8oD1PxpEG3nPKXYQKBgQC6AuMPRt3XBl1NkCrpSBy/uObFlFaP2Enpf39S +3OZ0Gv0XQrnSaL1kP8TMcz68rMrGX8DaWYsgytstR4W+jyy7WvZwsUu+GjTJ5aMG +77uEcEBpIi9CBzivfn7hPccE8ZgqPf+n4i6q66yxBJflW5xhvafJqDtW2LcPNbW/ +bvzdmQKBgExALRUXpq+5dbmkdXBHtvXdRDZ6rVmrnjy4nI5bPw+1GqQqk6uAR6B/ +F6NmLCQOO4PDG/cuatNHIr2FrwTmGdEL6ObLUGWn9Oer9gJhHVqqsY5I4sEPo4XX +stR0Yiw0buV6DL/moUO0HIM9Bjh96HJp+LxiIS6UCdIhMPp5HoQa +-----END RSA PRIVATE KEY-----` +) + func newServerInMemoryCache() *servercache.Cache { return servercache.NewCache( appstatecache.NewCache( @@ -52,13 +120,13 @@ func newServerInMemoryCache() *servercache.Cache { } func newNoopEnforcer() *rbac.Enforcer { - enf := rbac.NewEnforcer(fake.NewSimpleClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) + enf := rbac.NewEnforcer(fake.NewClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) enf.EnableEnforce(false) return enf } func newEnforcer() *rbac.Enforcer { - enforcer := rbac.NewEnforcer(fake.NewSimpleClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDRBACConfigMapName, nil) + enforcer := rbac.NewEnforcer(fake.NewClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDRBACConfigMapName, nil) _ = enforcer.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enforcer.SetDefaultRole("role:test") enforcer.SetClaimsEnforcerFunc(func(claims jwt.Claims, rvals ...interface{}) bool { @@ -161,7 +229,7 @@ func TestUpdateCluster_RejectInvalidParams(t *testing.T) { }, ) - enf := rbac.NewEnforcer(fake.NewSimpleClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) + enf := rbac.NewEnforcer(fake.NewClientset(test.NewFakeConfigMap()), test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) _ = enf.SetBuiltinPolicy(`p, role:test, clusters, *, https://127.0.0.1, allow p, role:test, clusters, *, allowed-project/*, allow`) enf.SetDefaultRole("role:test") @@ -238,6 +306,42 @@ func TestGetCluster_NameWithUrlEncodingButShouldNotBeUnescaped(t *testing.T) { assert.Equal(t, "test%2fing", cluster.Name) } +func TestGetCluster_CannotSetCADataAndInsecureTrue(t *testing.T) { + testNamespace := "default" + cluster := &v1alpha1.Cluster{ + Name: "my-cluster-name", + Server: "https://my-cluster-server", + Namespaces: []string{testNamespace}, + Config: v1alpha1.ClusterConfig{ + TLSClientConfig: v1alpha1.TLSClientConfig{ + Insecure: true, + CAData: []byte(rootCACert), + CertData: []byte(certData), + KeyData: []byte(keyData), + }, + }, + } + clientset := getClientset(nil, testNamespace) + db := db.NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset) + server := NewServer(db, newNoopEnforcer(), newServerInMemoryCache(), &kubetest.MockKubectlCmd{}) + + t.Run("Create Fails When CAData is Set and Insecure is True", func(t *testing.T) { + _, err := server.Create(context.Background(), &clusterapi.ClusterCreateRequest{ + Cluster: cluster, + }) + + assert.EqualError(t, err, `error getting REST config: Unable to apply K8s REST config defaults: specifying a root certificates file with the insecure flag is not allowed`) + }) + + cluster.Config.TLSClientConfig.CAData = nil + t.Run("Create Succeeds When CAData is nil and Insecure is True", func(t *testing.T) { + _, err := server.Create(context.Background(), &clusterapi.ClusterCreateRequest{ + Cluster: cluster, + }) + require.NoError(t, err) + }) +} + func TestUpdateCluster_NoFieldsPaths(t *testing.T) { db := &dbmocks.ArgoDB{} var updated *v1alpha1.Cluster @@ -381,7 +485,7 @@ func TestDeleteClusterByName(t *testing.T) { Name: "foo", }) - assert.EqualError(t, err, `rpc error: code = PermissionDenied desc = permission denied`) + assert.EqualError(t, err, `failed to get cluster with permissions check: rpc error: code = PermissionDenied desc = permission denied`) }) t.Run("Delete Succeeds When Deleting by Name", func(t *testing.T) { @@ -403,9 +507,7 @@ func TestRotateAuth(t *testing.T) { } configMarshal, err := json.Marshal(config) - if err != nil { - t.Errorf("failed to marshal config for test: %v", err) - } + require.NoError(t, err, "failed to marshal config for test") clientset := getClientset(nil, testNamespace, &corev1.Secret{ @@ -460,7 +562,7 @@ func TestRotateAuth(t *testing.T) { Name: "foo", }) - assert.EqualError(t, err, `rpc error: code = PermissionDenied desc = permission denied`) + assert.EqualError(t, err, `failed to get cluster with permissions check: rpc error: code = PermissionDenied desc = permission denied`) }) // While the tests results for the next two tests result in an error, they do @@ -471,8 +573,7 @@ func TestRotateAuth(t *testing.T) { Name: "my-cluster-name", }) - require.Error(t, err) - assert.Contains(t, err.Error(), "Get \"https://my-cluster-name/") + assert.ErrorContains(t, err, "Get \"https://my-cluster-name/") }) t.Run("RotateAuth by Server - Error from no such host", func(t *testing.T) { @@ -480,8 +581,7 @@ func TestRotateAuth(t *testing.T) { Server: "https://my-cluster-name", }) - require.Error(t, err) - assert.Contains(t, err.Error(), "Get \"https://my-cluster-name/") + assert.ErrorContains(t, err, "Get \"https://my-cluster-name/") }) } @@ -506,7 +606,7 @@ func getClientset(config map[string]string, ns string, objects ...runtime.Object }, Data: config, } - return fake.NewSimpleClientset(append(objects, &cm, &secret)...) + return fake.NewClientset(append(objects, &cm, &secret)...) } func TestListCluster(t *testing.T) { @@ -614,9 +714,7 @@ func TestListCluster(t *testing.T) { t.Errorf("Server.List() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("Server.List() = %v, want %v", got, tt.want) - } + assert.Truef(t, reflect.DeepEqual(got, tt.want), "Server.List() = %v, want %v", got, tt.want) }) } } @@ -699,14 +797,12 @@ func TestNoClusterEnumeration(t *testing.T) { _, err := server.Get(context.Background(), &clusterapi.ClusterQuery{ Name: "cluster-not-exists", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") _, err = server.Get(context.Background(), &clusterapi.ClusterQuery{ Name: "test/ing", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("Update", func(t *testing.T) { @@ -715,57 +811,49 @@ func TestNoClusterEnumeration(t *testing.T) { Name: "cluster-not-exists", }, }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") _, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{ Cluster: &v1alpha1.Cluster{ Name: "test/ing", }, }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("Delete", func(t *testing.T) { _, err := server.Delete(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.2", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") _, err = server.Delete(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.1", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("RotateAuth", func(t *testing.T) { _, err := server.RotateAuth(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.2", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") _, err = server.RotateAuth(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.1", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) t.Run("InvalidateCache", func(t *testing.T) { _, err := server.InvalidateCache(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.2", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + require.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") _, err = server.InvalidateCache(context.Background(), &clusterapi.ClusterQuery{ Server: "https://127.0.0.1", }) - require.Error(t, err) - assert.Equal(t, common.PermissionDeniedAPIError.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about cluster existence") + assert.ErrorIs(t, err, common.PermissionDeniedAPIError, "error message must be _only_ the permission error, to avoid leaking information about cluster existence") }) } diff --git a/server/extension/extension.go b/server/extension/extension.go index 706dfbbb31abd..d28d3aac5dc9f 100644 --- a/server/extension/extension.go +++ b/server/extension/extension.go @@ -33,6 +33,12 @@ const ( DefaultIdleConnectionTimeout = 60 * time.Second DefaultMaxIdleConnections = 30 + // HeaderArgoCDNamespace defines the namespace of the + // argo control plane to be passed to the extension handler. + // Example: + // Argocd-Namespace: "namespace" + HeaderArgoCDNamespace = "Argocd-Namespace" + // HeaderArgoCDApplicationName defines the name of the // expected application header to be passed to the extension // handler. The header value must follow the format: @@ -333,6 +339,7 @@ type RbacEnforcer interface { // and handling proxy extensions. type Manager struct { log *log.Entry + namespace string settings SettingsGetter application ApplicationGetter project ProjectGetter @@ -355,9 +362,10 @@ type ExtensionMetricsRegistry interface { } // NewManager will initialize a new manager. -func NewManager(log *log.Entry, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer, ug UserGetter) *Manager { +func NewManager(log *log.Entry, namespace string, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer, ug UserGetter) *Manager { return &Manager{ log: log, + namespace: namespace, settings: sg, application: ag, project: pg, @@ -402,28 +410,46 @@ func proxyKey(extName, cName, cServer string) ProxyKey { } func parseAndValidateConfig(s *settings.ArgoCDSettings) (*ExtensionConfigs, error) { - if s.ExtensionConfig == "" { + if len(s.ExtensionConfig) == 0 { return nil, fmt.Errorf("no extensions configurations found") } - extConfigMap := map[string]interface{}{} - err := yaml.Unmarshal([]byte(s.ExtensionConfig), &extConfigMap) - if err != nil { - return nil, fmt.Errorf("invalid extension config: %w", err) - } - - parsedExtConfig := settings.ReplaceMapSecrets(extConfigMap, s.Secrets) - parsedExtConfigBytes, err := yaml.Marshal(parsedExtConfig) - if err != nil { - return nil, fmt.Errorf("error marshaling parsed extension config: %w", err) - } - configs := ExtensionConfigs{} - err = yaml.Unmarshal(parsedExtConfigBytes, &configs) - if err != nil { - return nil, fmt.Errorf("invalid parsed extension config: %w", err) + for extName, extConfig := range s.ExtensionConfig { + extConfigMap := map[string]interface{}{} + err := yaml.Unmarshal([]byte(extConfig), &extConfigMap) + if err != nil { + return nil, fmt.Errorf("invalid extension config: %w", err) + } + + parsedExtConfig := settings.ReplaceMapSecrets(extConfigMap, s.Secrets) + parsedExtConfigBytes, err := yaml.Marshal(parsedExtConfig) + if err != nil { + return nil, fmt.Errorf("error marshaling parsed extension config: %w", err) + } + // empty extName means that this is the main configuration defined by + // the 'extension.config' configmap key + if extName == "" { + mainConfig := ExtensionConfigs{} + err = yaml.Unmarshal(parsedExtConfigBytes, &mainConfig) + if err != nil { + return nil, fmt.Errorf("invalid parsed extension config: %w", err) + } + configs.Extensions = append(configs.Extensions, mainConfig.Extensions...) + } else { + backendConfig := BackendConfig{} + err = yaml.Unmarshal(parsedExtConfigBytes, &backendConfig) + if err != nil { + return nil, fmt.Errorf("invalid parsed backend extension config for extension %s: %w", extName, err) + } + ext := ExtensionConfig{ + Name: extName, + Backend: backendConfig, + } + configs.Extensions = append(configs.Extensions, ext) + } } - err = validateConfigs(&configs) + err := validateConfigs(&configs) if err != nil { return nil, fmt.Errorf("validation error: %w", err) } @@ -538,7 +564,7 @@ func (m *Manager) RegisterExtensions() error { if err != nil { return fmt.Errorf("error getting settings: %w", err) } - if settings.ExtensionConfig == "" { + if len(settings.ExtensionConfig) == 0 { m.log.Infof("No extensions configured.") return nil } @@ -740,7 +766,7 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) { user := m.userGetter.GetUser(r.Context()) groups := m.userGetter.GetGroups(r.Context()) - prepareRequest(r, extName, app, user, groups) + prepareRequest(r, m.namespace, extName, app, user, groups) m.log.Debugf("proxing request for extension %q", extName) // httpsnoop package is used to properly wrap the responseWriter // and avoid optional intefaces issue: @@ -763,11 +789,13 @@ func registerMetrics(extName string, metrics httpsnoop.Metrics, extensionMetrics // the Argo CD extension API section from it. It provides additional information to // the backend service appending them in the outgoing request headers. The appended // headers are: +// - Control plane namespace // - Cluster destination name // - Cluster destination server // - Argo CD authenticated username -func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application, username string, groups []string) { +func prepareRequest(r *http.Request, namespace string, extName string, app *v1alpha1.Application, username string, groups []string) { r.URL.Path = strings.TrimPrefix(r.URL.Path, fmt.Sprintf("%s/%s", URLPrefix, extName)) + r.Header.Set(HeaderArgoCDNamespace, namespace) if app.Spec.Destination.Name != "" { r.Header.Set(HeaderArgoCDTargetClusterName, app.Spec.Destination.Name) } diff --git a/server/extension/extension_test.go b/server/extension/extension_test.go index 300e1e89a490d..3a92fcfeffb8f 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -27,10 +27,8 @@ import ( func TestValidateHeaders(t *testing.T) { t.Run("will build RequestResources successfully", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "namespace:app-name") r.Header.Add(extension.HeaderArgoCDProjectName, "project-name") @@ -46,10 +44,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if application is malformatted", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "no-namespace") // when @@ -61,10 +57,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if application header is missing", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDProjectName, "project-name") // when @@ -76,10 +70,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if project header is missing", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "namespace:app-name") // when @@ -91,10 +83,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if invalid namespace", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "bad%namespace:app-name") r.Header.Add(extension.HeaderArgoCDProjectName, "project-name") @@ -107,10 +97,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if invalid app name", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "namespace:bad@app") r.Header.Add(extension.HeaderArgoCDProjectName, "project-name") @@ -123,10 +111,8 @@ func TestValidateHeaders(t *testing.T) { }) t.Run("will return error if invalid project name", func(t *testing.T) { // given - r, err := http.NewRequest("Get", "http://null", nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + r, err := http.NewRequest(http.MethodGet, "http://null", nil) + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "namespace:app") r.Header.Add(extension.HeaderArgoCDProjectName, "bad^project") @@ -150,7 +136,7 @@ func TestRegisterExtensions(t *testing.T) { logger, _ := test.NewNullLogger() logEntry := logger.WithContext(context.Background()) - m := extension.NewManager(logEntry, settMock, nil, nil, nil, nil) + m := extension.NewManager(logEntry, "", settMock, nil, nil, nil, nil) return &fixture{ settingsGetterMock: settMock, @@ -162,12 +148,16 @@ func TestRegisterExtensions(t *testing.T) { t.Parallel() f := setup() settings := &settings.ArgoCDSettings{ - ExtensionConfig: getExtensionConfigString(), + ExtensionConfig: map[string]string{ + "": getExtensionConfigString(), + "another-ext": getSingleExtensionConfigString(), + }, } f.settingsGetterMock.On("Get", mock.Anything).Return(settings, nil) expectedProxyRegistries := []string{ "external-backend", "some-backend", + "another-ext", } // when @@ -223,7 +213,9 @@ func TestRegisterExtensions(t *testing.T) { t.Parallel() f := setup() settings := &settings.ArgoCDSettings{ - ExtensionConfig: tc.configYaml, + ExtensionConfig: map[string]string{ + "": tc.configYaml, + }, } f.settingsGetterMock.On("Get", mock.Anything).Return(settings, nil) @@ -248,6 +240,7 @@ func TestCallExtension(t *testing.T) { userMock *mocks.UserGetter manager *extension.Manager } + defaultServerNamespace := "control-plane-ns" defaultProjectName := "project-name" setup := func() *fixture { @@ -260,7 +253,7 @@ func TestCallExtension(t *testing.T) { logger, _ := test.NewNullLogger() logEntry := logger.WithContext(context.Background()) - m := extension.NewManager(logEntry, settMock, appMock, projMock, rbacMock, userMock) + m := extension.NewManager(logEntry, defaultServerNamespace, settMock, appMock, projMock, rbacMock, userMock) m.AddMetricsRegistry(metricsMock) mux := http.NewServeMux() @@ -361,8 +354,10 @@ func TestCallExtension(t *testing.T) { secrets["extension.auth.header2"] = "Bearer another-bearer-token" settings := &settings.ArgoCDSettings{ - ExtensionConfig: configYaml, - Secrets: secrets, + ExtensionConfig: map[string]string{ + "": configYaml, + }, + Secrets: secrets, } f.settingsGetterMock.On("Get", mock.Anything).Return(settings, nil) } @@ -370,9 +365,7 @@ func TestCallExtension(t *testing.T) { startTestServer := func(t *testing.T, f *fixture) *httptest.Server { t.Helper() err := f.manager.RegisterExtensions() - if err != nil { - t.Fatalf("error starting test server: %s", err) - } + require.NoError(t, err, "error starting test server") return httptest.NewServer(f.mux) } @@ -387,9 +380,7 @@ func TestCallExtension(t *testing.T) { newExtensionRequest := func(t *testing.T, method, url string) *http.Request { t.Helper() r, err := http.NewRequest(method, url, nil) - if err != nil { - t.Fatalf("error initializing request: %s", err) - } + require.NoError(t, err, "error initializing request") r.Header.Add(extension.HeaderArgoCDApplicationName, "namespace:app-name") r.Header.Add(extension.HeaderArgoCDProjectName, defaultProjectName) return r @@ -444,6 +435,7 @@ func TestCallExtension(t *testing.T) { require.NoError(t, err) actual := strings.TrimSuffix(string(body), "\n") assert.Equal(t, backendResponse, actual) + assert.Equal(t, defaultServerNamespace, resp.Header.Get(extension.HeaderArgoCDNamespace)) assert.Equal(t, clusterURL, resp.Header.Get(extension.HeaderArgoCDTargetClusterURL)) assert.Equal(t, "Bearer some-bearer-token", resp.Header.Get("Authorization")) assert.Equal(t, "some-user", resp.Header.Get(extension.HeaderArgoCDUsername)) @@ -794,6 +786,17 @@ extensions: ` } +func getSingleExtensionConfigString() string { + return ` +connectionTimeout: 10s +keepAlive: 11s +idleConnectionTimeout: 12s +maxIdleConnections: 30 +services: +- url: http://localhost:7777 +` +} + func getExtensionConfigNoService() string { return ` extensions: diff --git a/server/logout/logout_test.go b/server/logout/logout_test.go index 3d2bab2d3662d..83bf8ee5d92f3 100644 --- a/server/logout/logout_test.go +++ b/server/logout/logout_test.go @@ -3,10 +3,10 @@ package logout import ( "context" "errors" - "fmt" "net/http" "net/http/httptest" "regexp" + "strconv" "testing" "github.com/argoproj/argo-cd/v2/common" @@ -87,7 +87,7 @@ func TestConstructLogoutURL(t *testing.T) { } func TestHandlerConstructLogoutURL(t *testing.T) { - kubeClientWithOIDCConfig := fake.NewSimpleClientset( + kubeClientWithOIDCConfig := fake.NewClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -119,7 +119,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, }, ) - kubeClientWithOIDCConfigButNoURL := fake.NewSimpleClientset( + kubeClientWithOIDCConfigButNoURL := fake.NewClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -151,7 +151,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, }, ) - kubeClientWithOIDCConfigButNoLogoutURL := fake.NewSimpleClientset( + kubeClientWithOIDCConfigButNoLogoutURL := fake.NewClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -182,7 +182,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, }, ) - kubeClientWithoutOIDCAndMultipleURLs := fake.NewSimpleClientset( + kubeClientWithoutOIDCAndMultipleURLs := fake.NewClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -210,7 +210,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, }, ) - kubeClientWithoutOIDCConfig := fake.NewSimpleClientset( + kubeClientWithoutOIDCConfig := fake.NewClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -385,7 +385,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { if status := tt.responseRecorder.Code; status != http.StatusSeeOther { if !tt.wantErr { t.Error(tt.responseRecorder.Body.String()) - t.Error("handler returned wrong status code: " + fmt.Sprintf("%d", tt.responseRecorder.Code)) + t.Error("handler returned wrong status code: " + strconv.Itoa(tt.responseRecorder.Code)) } } else { if tt.wantErr { diff --git a/server/notification/notification_test.go b/server/notification/notification_test.go index 41e0306c84bd0..38467e7d59b75 100644 --- a/server/notification/notification_test.go +++ b/server/notification/notification_test.go @@ -35,7 +35,7 @@ func TestNotificationServer(t *testing.T) { require.NoError(t, err) cm.Namespace = testNamespace - kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&corev1.ConfigMap{ ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-notifications-cm", diff --git a/server/project/project.go b/server/project/project.go index 02d393564ddf0..cac913715b623 100644 --- a/server/project/project.go +++ b/server/project/project.go @@ -398,43 +398,31 @@ func (s *Server) Update(ctx context.Context, q *project.ProjectUpdateRequest) (* return nil, err } - var srcValidatedApps []v1alpha1.Application - var dstValidatedApps []v1alpha1.Application getProjectClusters := func(project string) ([]*v1alpha1.Cluster, error) { return s.db.GetProjectClusters(ctx, project) } - for _, a := range argo.FilterByProjects(appsList.Items, []string{q.Project.Name}) { - if oldProj.IsSourcePermitted(a.Spec.GetSource()) { - srcValidatedApps = append(srcValidatedApps, a) - } - - dstPermitted, err := oldProj.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) - if err != nil { - return nil, err - } - - if dstPermitted { - dstValidatedApps = append(dstValidatedApps, a) - } - } - invalidSrcCount := 0 invalidDstCount := 0 - for _, a := range srcValidatedApps { - if !q.Project.IsSourcePermitted(a.Spec.GetSource()) { + for _, a := range argo.FilterByProjects(appsList.Items, []string{q.Project.Name}) { + if oldProj.IsSourcePermitted(a.Spec.GetSource()) && !q.Project.IsSourcePermitted(a.Spec.GetSource()) { invalidSrcCount++ } - } - for _, a := range dstValidatedApps { - dstPermitted, err := q.Project.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) + + dstPermitted, err := oldProj.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) if err != nil { return nil, err } - if !dstPermitted { - invalidDstCount++ + if dstPermitted { + dstPermitted, err := q.Project.IsDestinationPermitted(a.Spec.Destination, getProjectClusters) + if err != nil { + return nil, err + } + if !dstPermitted { + invalidDstCount++ + } } } @@ -525,7 +513,10 @@ func (s *Server) GetSyncWindowsState(ctx context.Context, q *project.SyncWindows res := &project.SyncWindowsResponse{} - windows := proj.Spec.SyncWindows.Active() + windows, err := proj.Spec.SyncWindows.Active() + if err != nil { + return nil, err + } if windows.HasWindows() { res.Windows = *windows } else { diff --git a/server/project/project_test.go b/server/project/project_test.go index 41b8af9241e39..d4d9c3e40e4eb 100644 --- a/server/project/project_test.go +++ b/server/project/project_test.go @@ -38,10 +38,10 @@ import ( const testNamespace = "default" -var testEnableEventList []string = argo.DefaultEnableEventList() +var testEnableEventList = argo.DefaultEnableEventList() func TestProjectServer(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&corev1.ConfigMap{ ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-cm", @@ -94,7 +94,7 @@ func TestProjectServer(t *testing.T) { role1 := v1alpha1.ProjectRole{Name: roleName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}} projectWithRole.Spec.Roles = append(projectWithRole.Spec.Roles, role1) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) + projectServer := NewServer("default", fake.NewClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) err := projectServer.NormalizeProjs() require.NoError(t, err) @@ -196,6 +196,7 @@ func TestProjectServer(t *testing.T) { require.Error(t, err) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) + assert.Equal(t, "as a result of project update 1 applications destination became invalid", statusCode.Message()) }) t.Run("TestRemoveSourceSuccessful", func(t *testing.T) { @@ -232,6 +233,7 @@ func TestProjectServer(t *testing.T) { require.Error(t, err) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) + assert.Equal(t, "as a result of project update 1 applications source became invalid", statusCode.Message()) }) t.Run("TestRemoveSourceUsedByAppSuccessfulIfPermittedByAnotherSrc", func(t *testing.T) { @@ -318,6 +320,7 @@ func TestProjectServer(t *testing.T) { require.Error(t, err) statusCode, _ := status.FromError(err) assert.Equal(t, codes.InvalidArgument, statusCode.Code()) + assert.Equal(t, "project is referenced by 1 applications", statusCode.Message()) }) // configure a user named "admin" which is denied by default @@ -583,7 +586,7 @@ p, role:admin, projects, update, *, allow`) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) - assert.Contains(t, err.Error(), "object must be of form 'test/*', 'test[/]/' or 'test/'") + assert.ErrorContains(t, err, "object must be of form 'test/*', 'test[/]/' or 'test/'") }) t.Run("TestValidateProjectIncorrectProjectInRoleFailure", func(t *testing.T) { @@ -602,7 +605,7 @@ p, role:admin, projects, update, *, allow`) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) - assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'") + assert.ErrorContains(t, err, "policy subject must be: 'proj:test:testRole'") }) t.Run("TestValidateProjectIncorrectTokenInRoleFailure", func(t *testing.T) { @@ -621,7 +624,7 @@ p, role:admin, projects, update, *, allow`) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) - assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'") + assert.ErrorContains(t, err, "policy subject must be: 'proj:test:testRole'") }) t.Run("TestValidateProjectInvalidEffectFailure", func(t *testing.T) { @@ -639,7 +642,7 @@ p, role:admin, projects, update, *, allow`) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) - assert.Contains(t, err.Error(), "effect must be: 'allow' or 'deny'") + assert.ErrorContains(t, err, "effect must be: 'allow' or 'deny'") }) t.Run("TestNormalizeProjectRolePolicies", func(t *testing.T) { @@ -685,7 +688,7 @@ p, role:admin, projects, update, *, allow`) argoDB := db.NewDB("default", settingsMgr, kubeclientset) projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) res, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: "incorrect"}) - assert.Contains(t, err.Error(), "not found") + require.ErrorContains(t, err, "not found") assert.Nil(t, res) }) diff --git a/server/project/util_test.go b/server/project/util_test.go index 780d74fb34ab4..2cae39f41b6d3 100644 --- a/server/project/util_test.go +++ b/server/project/util_test.go @@ -3,6 +3,8 @@ package project import ( "reflect" "testing" + + "github.com/stretchr/testify/assert" ) func TestUnique(t *testing.T) { @@ -39,9 +41,8 @@ func TestUnique(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := unique(tt.slice); !reflect.DeepEqual(got, tt.want) { - t.Errorf("unique() = %v, want %v", got, tt.want) - } + got := unique(tt.slice) + assert.Truef(t, reflect.DeepEqual(got, tt.want), "unique() = %v, want %v", got, tt.want) }) } } diff --git a/server/rbacpolicy/rbacpolicy.go b/server/rbacpolicy/rbacpolicy.go index 0be623ae7819f..ea2b0ee0c166d 100644 --- a/server/rbacpolicy/rbacpolicy.go +++ b/server/rbacpolicy/rbacpolicy.go @@ -14,17 +14,18 @@ import ( const ( // please add new items to Resources - ResourceClusters = "clusters" - ResourceProjects = "projects" - ResourceApplications = "applications" - ResourceApplicationSets = "applicationsets" - ResourceRepositories = "repositories" - ResourceCertificates = "certificates" - ResourceAccounts = "accounts" - ResourceGPGKeys = "gpgkeys" - ResourceLogs = "logs" - ResourceExec = "exec" - ResourceExtensions = "extensions" + ResourceClusters = "clusters" + ResourceProjects = "projects" + ResourceApplications = "applications" + ResourceApplicationSets = "applicationsets" + ResourceRepositories = "repositories" + ResourceWriteRepositories = "write-repositories" + ResourceCertificates = "certificates" + ResourceAccounts = "accounts" + ResourceGPGKeys = "gpgkeys" + ResourceLogs = "logs" + ResourceExec = "exec" + ResourceExtensions = "extensions" // please add new items to Actions ActionGet = "get" @@ -45,9 +46,13 @@ var ( ResourceApplications, ResourceApplicationSets, ResourceRepositories, + ResourceWriteRepositories, ResourceCertificates, + ResourceAccounts, + ResourceGPGKeys, ResourceLogs, ResourceExec, + ResourceExtensions, } Actions = []string{ ActionGet, @@ -56,6 +61,8 @@ var ( ActionDelete, ActionSync, ActionOverride, + ActionAction, + ActionInvoke, } ) diff --git a/server/rbacpolicy/rbacpolicy_test.go b/server/rbacpolicy/rbacpolicy_test.go index 90de18ea4e0b7..ae8a9442e80df 100644 --- a/server/rbacpolicy/rbacpolicy_test.go +++ b/server/rbacpolicy/rbacpolicy_test.go @@ -49,7 +49,7 @@ func newFakeProj() *argoappv1.AppProject { } func TestEnforceAllPolicies(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap()) projLister := test.NewFakeProjLister(newFakeProj()) enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) enf.EnableLog(true) @@ -90,7 +90,7 @@ func TestEnforceAllPolicies(t *testing.T) { } func TestEnforceActionActions(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap()) projLister := test.NewFakeProjLister(newFakeProj()) enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) enf.EnableLog(true) @@ -123,7 +123,7 @@ p, cam, applications, %s/argoproj.io/Rollout/resume, my-proj/*, allow } func TestInvalidatedCache(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap()) projLister := test.NewFakeProjLister(newFakeProj()) enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) enf.EnableLog(true) diff --git a/server/repocreds/repocreds.go b/server/repocreds/repocreds.go index 5c0c819598fb3..4c3c2d1253db8 100644 --- a/server/repocreds/repocreds.go +++ b/server/repocreds/repocreds.go @@ -65,6 +65,30 @@ func (s *Server) ListRepositoryCredentials(ctx context.Context, q *repocredspkg. return &appsv1.RepoCredsList{Items: items}, nil } +// ListWriteRepositoryCredentials returns a list of all configured repository credential sets +func (s *Server) ListWriteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsQuery) (*appsv1.RepoCredsList, error) { + urls, err := s.db.ListRepositoryCredentials(ctx) + if err != nil { + return nil, err + } + items := make([]appsv1.RepoCreds, 0) + for _, url := range urls { + if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionGet, url) { + repo, err := s.db.GetWriteRepositoryCredentials(ctx, url) + if err != nil { + return nil, err + } + if repo != nil && repo.Password != "" { + items = append(items, appsv1.RepoCreds{ + URL: url, + Username: repo.Username, + }) + } + } + } + return &appsv1.RepoCredsList{Items: items}, nil +} + // CreateRepositoryCredentials creates a new credential set in the configuration func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsCreateRequest) (*appsv1.RepoCreds, error) { if q.Creds == nil { @@ -99,6 +123,40 @@ func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspk return &appsv1.RepoCreds{URL: r.URL}, err } +// CreateWriteRepositoryCredentials creates a new credential set in the configuration +func (s *Server) CreateWriteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsCreateRequest) (*appsv1.RepoCreds, error) { + if q.Creds == nil { + return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") + } + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionCreate, q.Creds.URL); err != nil { + return nil, err + } + + r := q.Creds + + if r.URL == "" { + return nil, status.Errorf(codes.InvalidArgument, "must specify URL") + } + + _, err := s.db.CreateWriteRepositoryCredentials(ctx, r) + if status.Convert(err).Code() == codes.AlreadyExists { + // act idempotent if existing spec matches new spec + existing, getErr := s.db.GetWriteRepositoryCredentials(ctx, r.URL) + if getErr != nil { + return nil, status.Errorf(codes.Internal, "unable to check existing repository credentials details: %v", getErr) + } + + if reflect.DeepEqual(existing, r) { + err = nil + } else if q.Upsert { + return s.UpdateWriteRepositoryCredentials(ctx, &repocredspkg.RepoCredsUpdateRequest{Creds: r}) + } else { + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository credentials", existing, r)) + } + } + return &appsv1.RepoCreds{URL: r.URL}, err +} + // UpdateRepositoryCredentials updates a repository credential set func (s *Server) UpdateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsUpdateRequest) (*appsv1.RepoCreds, error) { if q.Creds == nil { @@ -111,6 +169,18 @@ func (s *Server) UpdateRepositoryCredentials(ctx context.Context, q *repocredspk return &appsv1.RepoCreds{URL: q.Creds.URL}, err } +// UpdateWriteRepositoryCredentials updates a repository credential set +func (s *Server) UpdateWriteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsUpdateRequest) (*appsv1.RepoCreds, error) { + if q.Creds == nil { + return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") + } + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionUpdate, q.Creds.URL); err != nil { + return nil, err + } + _, err := s.db.UpdateWriteRepositoryCredentials(ctx, q.Creds) + return &appsv1.RepoCreds{URL: q.Creds.URL}, err +} + // DeleteRepositoryCredentials removes a credential set from the configuration func (s *Server) DeleteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsDeleteRequest) (*repocredspkg.RepoCredsResponse, error) { if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionDelete, q.Url); err != nil { @@ -120,3 +190,13 @@ func (s *Server) DeleteRepositoryCredentials(ctx context.Context, q *repocredspk err := s.db.DeleteRepositoryCredentials(ctx, q.Url) return &repocredspkg.RepoCredsResponse{}, err } + +// DeleteWriteRepositoryCredentials removes a credential set from the configuration +func (s *Server) DeleteWriteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsDeleteRequest) (*repocredspkg.RepoCredsResponse, error) { + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionDelete, q.Url); err != nil { + return nil, err + } + + err := s.db.DeleteWriteRepositoryCredentials(ctx, q.Url) + return &repocredspkg.RepoCredsResponse{}, err +} diff --git a/server/repocreds/repocreds.proto b/server/repocreds/repocreds.proto index 3019bfdb5bc86..59151b264430b 100644 --- a/server/repocreds/repocreds.proto +++ b/server/repocreds/repocreds.proto @@ -43,6 +43,11 @@ service RepoCredsService { option (google.api.http).get = "/api/v1/repocreds"; } + //ListWriteRepositoryCredentials gets a list of all configured repository credential sets that have write access + rpc ListWriteRepositoryCredentials(RepoCredsQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCredsList) { + option (google.api.http).get = "/api/v1/write-repocreds"; + } + // CreateRepositoryCredentials creates a new repository credential set rpc CreateRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { @@ -51,6 +56,14 @@ service RepoCredsService { }; } + // CreateWriteRepositoryCredentials creates a new repository credential set with write access + rpc CreateWriteRepositoryCredentials(RepoCredsCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { + option (google.api.http) = { + post: "/api/v1/write-repocreds" + body: "creds" + }; + } + // UpdateRepositoryCredentials updates a repository credential set rpc UpdateRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { option (google.api.http) = { @@ -59,9 +72,21 @@ service RepoCredsService { }; } + // UpdateWriteRepositoryCredentials updates a repository credential set with write access + rpc UpdateWriteRepositoryCredentials(RepoCredsUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepoCreds) { + option (google.api.http) = { + put: "/api/v1/write-repocreds/{creds.url}" + body: "creds" + }; + } + // DeleteRepositoryCredentials deletes a repository credential set from the configuration rpc DeleteRepositoryCredentials(RepoCredsDeleteRequest) returns (RepoCredsResponse) { option (google.api.http).delete = "/api/v1/repocreds/{url}"; } + // DeleteWriteRepositoryCredentials deletes a repository credential set with write access from the configuration + rpc DeleteWriteRepositoryCredentials(RepoCredsDeleteRequest) returns (RepoCredsResponse) { + option (google.api.http).delete = "/api/v1/write-repocreds/{url}"; + } } diff --git a/server/repository/repository.go b/server/repository/repository.go index 2e25f87ce19d1..191b720733e0f 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -16,7 +16,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/cache" - "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" @@ -35,14 +34,15 @@ import ( // Server provides a Repository service type Server struct { - db db.ArgoDB - repoClientset apiclient.Clientset - enf *rbac.Enforcer - cache *servercache.Cache - appLister applisters.ApplicationLister - projLister cache.SharedIndexInformer - settings *settings.SettingsManager - namespace string + db db.ArgoDB + repoClientset apiclient.Clientset + enf *rbac.Enforcer + cache *servercache.Cache + appLister applisters.ApplicationLister + projLister cache.SharedIndexInformer + settings *settings.SettingsManager + namespace string + hydratorEnabled bool } // NewServer returns a new instance of the Repository service @@ -55,16 +55,18 @@ func NewServer( projLister cache.SharedIndexInformer, namespace string, settings *settings.SettingsManager, + hydratorEnabled bool, ) *Server { return &Server{ - db: db, - repoClientset: repoClientset, - enf: enf, - cache: cache, - appLister: appLister, - projLister: projLister, - namespace: namespace, - settings: settings, + db: db, + repoClientset: repoClientset, + enf: enf, + cache: cache, + appLister: appLister, + projLister: projLister, + namespace: namespace, + settings: settings, + hydratorEnabled: hydratorEnabled, } } @@ -78,6 +80,14 @@ func (s *Server) getRepo(ctx context.Context, url, project string) (*appsv1.Repo return repo, nil } +func (s *Server) getWriteRepo(ctx context.Context, url, project string) (*appsv1.Repository, error) { + repo, err := s.db.GetWriteRepository(ctx, url, project) + if err != nil { + return nil, errPermissionDenied + } + return repo, nil +} + func createRBACObject(project string, repo string) string { if project != "" { return project + "/" + repo @@ -128,6 +138,7 @@ func (s *Server) List(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1. // Get return the requested configured repository by URL and the state of its connections. func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.Repository, error) { + // ListRepositories normalizes the repo, sanitizes it, and augments it with connection details. repo, err := getRepository(ctx, s.ListRepositories, q) if err != nil { return nil, err @@ -137,7 +148,6 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R return nil, err } - // getRepo does not return an error for unconfigured repositories, so we are checking here exists, err := s.db.RepositoryExists(ctx, q.Repo, repo.Project) if err != nil { return nil, err @@ -146,30 +156,32 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R return nil, status.Errorf(codes.NotFound, "repo '%s' not found", q.Repo) } - // For backwards compatibility, if we have no repo type set assume a default - rType := repo.Type - if rType == "" { - rType = common.DefaultRepoType + return repo, nil +} + +func (s *Server) GetWrite(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.Repository, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") } - // remove secrets - item := appsv1.Repository{ - Repo: repo.Repo, - Type: rType, - Name: repo.Name, - Username: repo.Username, - Insecure: repo.IsInsecure(), - EnableLFS: repo.EnableLFS, - GithubAppId: repo.GithubAppId, - GithubAppInstallationId: repo.GithubAppInstallationId, - GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL, - Proxy: repo.Proxy, - Project: repo.Project, - InheritedCreds: repo.InheritedCreds, + + repo, err := getRepository(ctx, s.ListWriteRepositories, q) + if err != nil { + return nil, err } - item.ConnectionState = s.getConnectionState(ctx, item.Repo, item.Project, q.ForceRefresh) + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)); err != nil { + return nil, err + } - return &item, nil + exists, err := s.db.WriteRepositoryExists(ctx, q.Repo, repo.Project) + if err != nil { + return nil, err + } + if !exists { + return nil, status.Errorf(codes.NotFound, "write repo '%s' not found", q.Repo) + } + + return repo, nil } // ListRepositories returns a list of all configured repositories and the state of their connections @@ -178,33 +190,44 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer if err != nil { return nil, err } + items, err := s.prepareRepoList(ctx, rbacpolicy.ResourceRepositories, repos, q.ForceRefresh) + if err != nil { + return nil, err + } + return &appsv1.RepositoryList{Items: items}, nil +} + +// ListWriteRepositories returns a list of all configured repositories where the user has write access and the state of +// their connections +func (s *Server) ListWriteRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.RepositoryList, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") + } + + repos, err := s.db.ListWriteRepositories(ctx) + if err != nil { + return nil, err + } + items, err := s.prepareRepoList(ctx, rbacpolicy.ResourceWriteRepositories, repos, q.ForceRefresh) + if err != nil { + return nil, err + } + return &appsv1.RepositoryList{Items: items}, nil +} + +// ListRepositoriesByAppProject returns a list of all configured repositories and the state of their connections. It +// normalizes, sanitizes, and filters out repositories that the user does not have access to in the specified project. +// It also sorts the repositories by project and repo name. +func (s *Server) prepareRepoList(ctx context.Context, resourceType string, repos []*appsv1.Repository, forceRefresh bool) (appsv1.Repositories, error) { items := appsv1.Repositories{} for _, repo := range repos { - if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, createRBACObject(repo.Project, repo.Repo)) { - // For backwards compatibility, if we have no repo type set assume a default - rType := repo.Type - if rType == "" { - rType = common.DefaultRepoType - } - // remove secrets - items = append(items, &appsv1.Repository{ - Repo: repo.Repo, - Type: rType, - Name: repo.Name, - Username: repo.Username, - Insecure: repo.IsInsecure(), - EnableLFS: repo.EnableLFS, - EnableOCI: repo.EnableOCI, - Proxy: repo.Proxy, - NoProxy: repo.NoProxy, - Project: repo.Project, - ForceHttpBasicAuth: repo.ForceHttpBasicAuth, - InheritedCreds: repo.InheritedCreds, - }) - } + items = append(items, repo.Normalize().Sanitized()) } - err = kube.RunAllAsync(len(items), func(i int) error { - items[i].ConnectionState = s.getConnectionState(ctx, items[i].Repo, items[i].Project, q.ForceRefresh) + items = items.Filter(func(r *appsv1.Repository) bool { + return s.enf.Enforce(ctx.Value("claims"), resourceType, rbacpolicy.ActionGet, createRBACObject(r.Project, r.Repo)) + }) + err := kube.RunAllAsync(len(items), func(i int) error { + items[i].ConnectionState = s.getConnectionState(ctx, items[i].Repo, items[i].Project, forceRefresh) return nil }) if err != nil { @@ -215,7 +238,7 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer second := items[j] return strings.Compare(fmt.Sprintf("%s/%s", first.Project, first.Repo), fmt.Sprintf("%s/%s", second.Project, second.Repo)) < 0 }) - return &appsv1.RepositoryList{Items: items}, nil + return items, nil } func (s *Server) ListRefs(ctx context.Context, q *repositorypkg.RepoQuery) (*apiclient.Refs, error) { @@ -441,7 +464,7 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea repo, err = existing, nil } else if q.Upsert { r.Project = q.Repo.Project - return s.UpdateRepository(ctx, &repositorypkg.RepoUpdateRequest{Repo: r}) + return s.db.UpdateRepository(ctx, r) } else { return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository", existing, r)) } @@ -452,6 +475,50 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil } +// CreateWriteRepository creates a repository configuration with write credentials +func (s *Server) CreateWriteRepository(ctx context.Context, q *repositorypkg.RepoCreateRequest) (*appsv1.Repository, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") + } + + if q.Repo == nil { + return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") + } + + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionCreate, createRBACObject(q.Repo.Project, q.Repo.Repo)); err != nil { + return nil, err + } + + if !q.Repo.HasCredentials() { + return nil, status.Errorf(codes.InvalidArgument, "missing credentials in request") + } + + err := s.testRepo(ctx, q.Repo) + if err != nil { + return nil, err + } + + repo, err := s.db.CreateWriteRepository(ctx, q.Repo) + if status.Convert(err).Code() == codes.AlreadyExists { + // act idempotent if existing spec matches new spec + existing, getErr := s.db.GetWriteRepository(ctx, q.Repo.Repo, q.Repo.Project) + if getErr != nil { + return nil, status.Errorf(codes.Internal, "unable to check existing repository details: %v", getErr) + } + if reflect.DeepEqual(existing, q.Repo) { + repo, err = existing, nil + } else if q.Upsert { + return s.db.UpdateWriteRepository(ctx, q.Repo) + } else { + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("write repository", existing, q.Repo)) + } + } + if err != nil { + return nil, err + } + return &appsv1.Repository{Repo: repo.Repo, Type: repo.Type, Name: repo.Name}, nil +} + // Update updates a repository or credential set // Deprecated: Use UpdateRepository() instead func (s *Server) Update(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) { @@ -481,6 +548,33 @@ func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpda return &appsv1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err } +// UpdateWriteRepository updates a repository configuration with write credentials +func (s *Server) UpdateWriteRepository(ctx context.Context, q *repositorypkg.RepoUpdateRequest) (*appsv1.Repository, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") + } + + if q.Repo == nil { + return nil, status.Errorf(codes.InvalidArgument, "missing payload in request") + } + + repo, err := s.getWriteRepo(ctx, q.Repo.Repo, q.Repo.Project) + if err != nil { + return nil, err + } + + // verify that user can do update inside project where repository is located + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionUpdate, createRBACObject(repo.Project, repo.Repo)); err != nil { + return nil, err + } + // verify that user can do update inside project where repository will be located + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionUpdate, createRBACObject(q.Repo.Project, q.Repo.Repo)); err != nil { + return nil, err + } + _, err = s.db.UpdateWriteRepository(ctx, q.Repo) + return &appsv1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err +} + // Delete removes a repository from the configuration // Deprecated: Use DeleteRepository() instead func (s *Server) Delete(ctx context.Context, q *repositorypkg.RepoQuery) (*repositorypkg.RepoResponse, error) { @@ -507,6 +601,25 @@ func (s *Server) DeleteRepository(ctx context.Context, q *repositorypkg.RepoQuer return &repositorypkg.RepoResponse{}, err } +// DeleteWriteRepository removes a repository from the configuration +func (s *Server) DeleteWriteRepository(ctx context.Context, q *repositorypkg.RepoQuery) (*repositorypkg.RepoResponse, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") + } + + repo, err := getRepository(ctx, s.ListWriteRepositories, q) + if err != nil { + return nil, err + } + + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionDelete, createRBACObject(repo.Project, repo.Repo)); err != nil { + return nil, err + } + + err = s.db.DeleteWriteRepository(ctx, repo.Repo, repo.Project) + return &repositorypkg.RepoResponse{}, err +} + // getRepository fetches a single repository which the user has access to. If only one repository can be found which // matches the same URL, that will be returned (this is for backward compatibility reasons). If multiple repositories // are matched, a repository is only returned if it matches the app project of the incoming request. @@ -590,10 +703,47 @@ func (s *Server) ValidateAccess(ctx context.Context, q *repositorypkg.RepoAccess return &repositorypkg.RepoResponse{}, nil } +// ValidateWriteAccess checks whether write access to a repository is possible with the +// given URL and credentials. +func (s *Server) ValidateWriteAccess(ctx context.Context, q *repositorypkg.RepoAccessQuery) (*repositorypkg.RepoResponse, error) { + if !s.hydratorEnabled { + return nil, status.Error(codes.Unimplemented, "hydrator is disabled") + } + + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceWriteRepositories, rbacpolicy.ActionCreate, createRBACObject(q.Project, q.Repo)); err != nil { + return nil, err + } + + repo := &appsv1.Repository{ + Repo: q.Repo, + Type: q.Type, + Name: q.Name, + Username: q.Username, + Password: q.Password, + SSHPrivateKey: q.SshPrivateKey, + Insecure: q.Insecure, + TLSClientCertData: q.TlsClientCertData, + TLSClientCertKey: q.TlsClientCertKey, + EnableOCI: q.EnableOci, + GithubAppPrivateKey: q.GithubAppPrivateKey, + GithubAppId: q.GithubAppID, + GithubAppInstallationId: q.GithubAppInstallationID, + GitHubAppEnterpriseBaseURL: q.GithubAppEnterpriseBaseUrl, + Proxy: q.Proxy, + GCPServiceAccountKey: q.GcpServiceAccountKey, + } + + err := s.testRepo(ctx, repo) + if err != nil { + return nil, err + } + return &repositorypkg.RepoResponse{}, nil +} + func (s *Server) testRepo(ctx context.Context, repo *appsv1.Repository) error { conn, repoClient, err := s.repoClientset.NewRepoServerClient() if err != nil { - return err + return fmt.Errorf("failed to connect to repo-server: %w", err) } defer io.Close(conn) diff --git a/server/repository/repository.proto b/server/repository/repository.proto index 379cbdeabf9cc..678cb7ecc583c 100644 --- a/server/repository/repository.proto +++ b/server/repository/repository.proto @@ -116,16 +116,26 @@ service RepositoryService { option deprecated = true; } - // Get returns a repository or its credentials + // Get returns a repository or its credentials rpc Get(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http).get = "/api/v1/repositories/{repo}"; } + // GetWrite returns a repository or its write credentials + rpc GetWrite(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { + option (google.api.http).get = "/api/v1/write-repositories/{repo}"; + } + // ListRepositories gets a list of all configured repositories rpc ListRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList) { option (google.api.http).get = "/api/v1/repositories"; } + // ListWriteRepositories gets a list of all configured write repositories + rpc ListWriteRepositories(RepoQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RepositoryList) { + option (google.api.http).get = "/api/v1/write-repositories"; + } + rpc ListRefs(RepoQuery) returns (Refs) { option (google.api.http).get = "/api/v1/repositories/{repo}/refs"; } @@ -165,6 +175,14 @@ service RepositoryService { }; } + // CreateWriteRepository creates a new write repository configuration + rpc CreateWriteRepository(RepoCreateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { + option (google.api.http) = { + post: "/api/v1/write-repositories" + body: "repo" + }; + } + // Update updates a repo or repo credential set rpc Update(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { option (google.api.http) = { @@ -182,6 +200,14 @@ service RepositoryService { }; } + // UpdateWriteRepository updates a write repository configuration + rpc UpdateWriteRepository(RepoUpdateRequest) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository) { + option (google.api.http) = { + put: "/api/v1/write-repositories/{repo.repo}" + body: "repo" + }; + } + // Delete deletes a repository from the configuration rpc Delete(RepoQuery) returns (RepoResponse) { option (google.api.http).delete = "/api/v1/repositories/{repo}"; @@ -193,6 +219,11 @@ service RepositoryService { option (google.api.http).delete = "/api/v1/repositories/{repo}"; } + // DeleteWriteRepository deletes a write repository from the configuration + rpc DeleteWriteRepository(RepoQuery) returns (RepoResponse) { + option (google.api.http).delete = "/api/v1/write-repositories/{repo}"; + } + // ValidateAccess validates access to a repository with given parameters rpc ValidateAccess(RepoAccessQuery) returns (RepoResponse) { option (google.api.http) = { @@ -200,4 +231,12 @@ service RepositoryService { body: "repo" }; } + + // ValidateWriteAccess validates write access to a repository with given parameters + rpc ValidateWriteAccess(RepoAccessQuery) returns (RepoResponse) { + option (google.api.http) = { + post: "/api/v1/write-repositories/{repo}/validate" + body: "repo" + }; + } } diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index 72354633048dc..7b4b77bca2ab1 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -21,6 +21,7 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apiclient/repository" + repositorypkg "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" @@ -266,7 +267,7 @@ func TestRepositoryServer(t *testing.T) { repoServerClient := mocks.RepoServerServiceClient{} repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} - s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projInformer, testNamespace, settingsMgr, false) url := "https://test" repo, _ := s.getRepo(context.TODO(), url, "") assert.Equal(t, repo.Repo, url) @@ -277,7 +278,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, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, argoDB, enforcer, nil, appLister, projInformer, testNamespace, settingsMgr, false) url := "https://test" _, err := s.ValidateAccess(context.TODO(), &repository.RepoAccessQuery{ Repo: url, @@ -296,7 +297,7 @@ func TestRepositoryServer(t *testing.T) { 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, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) @@ -321,7 +322,7 @@ func TestRepositoryServer(t *testing.T) { db.On("GetRepository", context.TODO(), url, "").Return(testRepo, nil) db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) @@ -342,7 +343,7 @@ 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, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) @@ -361,12 +362,77 @@ func TestRepositoryServer(t *testing.T) { 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, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.Get(context.TODO(), &repository.RepoQuery{ Repo: url, }) assert.Nil(t, repo) - assert.Equal(t, "rpc error: code = NotFound desc = repo 'https://test' not found", err.Error()) + assert.EqualError(t, err, "rpc error: code = NotFound desc = repo 'https://test' not found") + }) + + t.Run("Test_GetRepoIsSanitized", func(t *testing.T) { + repoServerClient := mocks.RepoServerServiceClient{} + repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) + repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} + + url := "https://test" + db := &dbmocks.ArgoDB{} + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url, Username: "test", Password: "it's a secret", GitHubAppEnterpriseBaseURL: "https://ghe.example.com/api/v3", GithubAppId: 123456, GithubAppInstallationId: 789}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test", Password: "it's a secret"}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) + + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ + Repo: url, + }) + require.NoError(t, err) + assert.Equal(t, "https://test", repo.Repo) + assert.Equal(t, "https://ghe.example.com/api/v3", repo.GitHubAppEnterpriseBaseURL) + assert.Equal(t, int64(123456), repo.GithubAppId) + assert.Equal(t, int64(789), repo.GithubAppInstallationId) + assert.Empty(t, repo.Password) + }) + + t.Run("Test_GetRepoIsNormalized", func(t *testing.T) { + repoServerClient := mocks.RepoServerServiceClient{} + repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) + repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} + + url := "https://test" + db := &dbmocks.ArgoDB{} + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: url}}, nil) + db.On("GetRepository", context.TODO(), url, "").Return(&appsv1.Repository{Repo: url, Username: "test"}, nil) + db.On("RepositoryExists", context.TODO(), url, "").Return(true, nil) + + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ + Repo: url, + }) + require.NoError(t, err) + assert.Equal(t, "https://test", repo.Repo) + assert.Equal(t, common.DefaultRepoType, repo.Type) + }) + + t.Run("Test_GetRepoHasConnectionState", func(t *testing.T) { + repoServerClient := mocks.RepoServerServiceClient{} + repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{ + VerifiedRepository: true, + }, nil) + repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} + + url := "https://test" + db := &dbmocks.ArgoDB{} + db.On("ListRepositories", context.TODO()).Return([]*appsv1.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, appLister, projInformer, testNamespace, settingsMgr, false) + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ + Repo: url, + }) + require.NoError(t, err) + require.NotNil(t, repo.ConnectionState) + assert.Equal(t, appsv1.ConnectionStatusSuccessful, repo.ConnectionState.Status) }) t.Run("Test_CreateRepositoryWithoutUpsert", func(t *testing.T) { @@ -381,7 +447,7 @@ func TestRepositoryServer(t *testing.T) { Project: "proj", }, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{ Repo: &appsv1.Repository{ Repo: "test", @@ -397,24 +463,27 @@ func TestRepositoryServer(t *testing.T) { repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} + r := &appsv1.Repository{ + Repo: "test", + Username: "test", + } + db := &dbmocks.ArgoDB{} 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) + db.On("UpdateRepository", context.TODO(), mock.Anything).Return(r, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) repo, err := s.CreateRepository(context.TODO(), &repository.RepoCreateRequest{ - Repo: &appsv1.Repository{ - Repo: "test", - Username: "test", - }, + Repo: r, Upsert: true, }) require.NoError(t, err) + require.NotNil(t, repo) assert.Equal(t, "test", repo.Repo) }) @@ -430,7 +499,7 @@ func TestRepositoryServer(t *testing.T) { db.On("ListHelmRepositories", context.TODO(), mock.Anything).Return(nil, nil) db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{&fakeRepo, &fakeRepo}, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projInformer, testNamespace, settingsMgr, false) resp, err := s.ListRepositories(context.TODO(), &repository.RepoQuery{}) require.NoError(t, err) assert.Len(t, resp.Items, 2) @@ -452,7 +521,7 @@ func TestRepositoryServerListApps(t *testing.T) { db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", @@ -481,7 +550,7 @@ func TestRepositoryServerListApps(t *testing.T) { }, }, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", @@ -489,7 +558,7 @@ func TestRepositoryServerListApps(t *testing.T) { AppProject: "default", }) require.NoError(t, err) - assert.Len(t, resp.Items, 1) + require.Len(t, resp.Items, 1) assert.Equal(t, "path/to/dir", resp.Items[0].Path) assert.Equal(t, "Kustomize", resp.Items[0].Type) }) @@ -512,7 +581,7 @@ func TestRepositoryServerListApps(t *testing.T) { }, }, nil) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.ListApps(context.TODO(), &repository.RepoAppsQuery{ Repo: "https://test", Revision: "HEAD", @@ -539,7 +608,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, @@ -562,7 +631,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, @@ -584,7 +653,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { db.On("GetRepository", context.TODO(), url, "default").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, @@ -610,7 +679,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, @@ -635,7 +704,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProjNoSources) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: &appsv1.ApplicationSource{ RepoURL: url, @@ -661,7 +730,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: guestbookApp.Spec.GetSourcePtrByIndex(0), AppName: "guestbook", @@ -686,7 +755,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { repoServerClient.On("GetAppDetails", context.TODO(), mock.Anything).Return(&expectedResp, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp001) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) sources := multiSourceApp001.Spec.GetSources() assert.Len(t, sources, 2) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ @@ -727,7 +796,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { repoServerClient.On("GetAppDetails", context.TODO(), mock.MatchedBy(func(req *apiclient.RepoServerAppDetailsQuery) bool { return req.Source.RepoURL == url1 })).Return(&expectedResp1, nil) appLister, projLister := newAppAndProjLister(defaultProj, multiSourceApp002) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) sources := multiSourceApp002.Spec.GetSources() assert.Len(t, sources, 2) @@ -759,7 +828,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { db.On("GetRepository", context.TODO(), url, "mismatch").Return(&appsv1.Repository{Repo: url}, nil) appLister, projLister := newAppAndProjLister(defaultProj, guestbookApp) - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: guestbookApp.Spec.GetSourcePtrByIndex(0), AppName: "guestbook", @@ -780,7 +849,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { differentSource := guestbookApp.Spec.Source.DeepCopy() differentSource.Helm.ValueFiles = []string{"/etc/passwd"} - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: differentSource, AppName: "guestbook", @@ -806,7 +875,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { previousSource := guestbookApp.Status.History[0].Source.DeepCopy() previousSource.TargetRevision = guestbookApp.Status.History[0].Revision - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: previousSource, AppName: "guestbook", @@ -835,7 +904,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { differentSource := multiSourceApp001.Spec.Sources[0].DeepCopy() differentSource.Helm.ValueFiles = []string{"/etc/passwd"} - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: differentSource, AppName: multiSourceApp001AppName, @@ -863,7 +932,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { previousSource := multiSourceApp001.Status.History[0].Sources[0].DeepCopy() previousSource.TargetRevision = multiSourceApp001.Status.History[0].Revisions[0] - s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ Source: previousSource, AppName: multiSourceApp001AppName, @@ -1057,3 +1126,35 @@ func TestGetRepository(t *testing.T) { }) } } + +func TestDeleteRepository(t *testing.T) { + repositories := map[string]string{ + "valid": "https://bitbucket.org/workspace/repo.git", + // Check a wrongly formatter repo as well, see https://github.com/argoproj/argo-cd/issues/20921 + "invalid": "git clone https://bitbucket.org/workspace/repo.git", + } + + kubeclientset := fake.NewSimpleClientset(&argocdCM, &argocdSecret) + settingsMgr := settings.NewSettingsManager(context.Background(), kubeclientset, testNamespace) + + for name, repo := range repositories { + t.Run(name, func(t *testing.T) { + repoServerClient := mocks.RepoServerServiceClient{} + repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) + + repoServerClientset := mocks.Clientset{RepoServerServiceClient: &repoServerClient} + enforcer := newEnforcer(kubeclientset) + + db := &dbmocks.ArgoDB{} + db.On("DeleteRepository", context.TODO(), repo, "default").Return(nil) + db.On("ListRepositories", context.TODO()).Return([]*appsv1.Repository{{Repo: repo, Project: "default"}}, nil) + db.On("GetRepository", context.TODO(), repo, "default").Return(&appsv1.Repository{Repo: repo, Project: "default"}, nil) + appLister, projLister := newAppAndProjLister(defaultProj) + + s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr, false) + resp, err := s.DeleteRepository(context.TODO(), &repository.RepoQuery{Repo: repo, AppProject: "default"}) + require.NoError(t, err) + assert.Equal(t, repositorypkg.RepoResponse{}, *resp) + }) + } +} diff --git a/server/server.go b/server/server.go index 7ded3951a37c3..c9c93dc1be4d4 100644 --- a/server/server.go +++ b/server/server.go @@ -13,13 +13,17 @@ import ( "net/url" "os" "os/exec" + "os/signal" "path" "path/filepath" "reflect" "regexp" go_runtime "runtime" + "runtime/debug" "strings" gosync "sync" + "sync/atomic" + "syscall" "time" // nolint:staticcheck @@ -187,17 +191,20 @@ type ArgoCDServer struct { db db.ArgoDB // stopCh is the channel which when closed, will shutdown the Argo CD server - stopCh chan struct{} - userStateStorage util_session.UserStateStorage - indexDataInit gosync.Once - indexData []byte - indexDataErr error - staticAssets http.FileSystem - apiFactory api.Factory - secretInformer cache.SharedIndexInformer - configMapInformer cache.SharedIndexInformer - serviceSet *ArgoCDServiceSet - extensionManager *extension.Manager + stopCh chan os.Signal + userStateStorage util_session.UserStateStorage + indexDataInit gosync.Once + indexData []byte + indexDataErr error + staticAssets http.FileSystem + apiFactory api.Factory + secretInformer cache.SharedIndexInformer + configMapInformer cache.SharedIndexInformer + serviceSet *ArgoCDServiceSet + extensionManager *extension.Manager + shutdown func() + terminateRequested atomic.Bool + available atomic.Bool } type ArgoCDServerOpts struct { @@ -230,6 +237,7 @@ type ArgoCDServerOpts struct { EnableProxyExtension bool WebhookParallelism int EnableK8sEvent []string + HydratorEnabled bool } type ApplicationSetOpts struct { @@ -328,7 +336,10 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio ag := extension.NewDefaultApplicationGetter(appLister) pg := extension.NewDefaultProjectGetter(projLister, dbInstance) ug := extension.NewDefaultUserGetter(policyEnf) - em := extension.NewManager(logger, sg, ag, pg, enf, ug) + em := extension.NewManager(logger, opts.Namespace, sg, ag, pg, enf, ug) + noopShutdown := func() { + log.Error("API Server Shutdown function called but server is not started yet.") + } a := &ArgoCDServer{ ArgoCDServerOpts: opts, @@ -352,6 +363,8 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts Applicatio secretInformer: secretInformer, configMapInformer: configMapInformer, extensionManager: em, + shutdown: noopShutdown, + stopCh: make(chan os.Signal, 1), } err = a.logInClusterWarnings() @@ -369,6 +382,12 @@ const ( ) func (a *ArgoCDServer) healthCheck(r *http.Request) error { + if a.terminateRequested.Load() { + return errors.New("API Server is terminating and unable to serve requests.") + } + if !a.available.Load() { + return errors.New("API Server is not available. It either hasn't started or is restarting.") + } if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" { argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) _, err := argoDB.ListClusters(r.Context()) @@ -515,11 +534,19 @@ func (a *ArgoCDServer) Init(ctx context.Context) { // k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of // golang/protobuf). func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { + defer func() { + if r := recover(); r != nil { + log.WithField("trace", string(debug.Stack())).Error("Recovered from panic: ", r) + a.terminateRequested.Store(true) + a.shutdown() + } + }() + a.userStateStorage.Init(ctx) metricsServ := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) if a.RedisClient != nil { - cacheutil.CollectMetrics(a.RedisClient, metricsServ) + cacheutil.CollectMetrics(a.RedisClient, metricsServ, a.userStateStorage.GetLockObject()) } svcSet := newArgoCDServiceSet(a) @@ -561,7 +588,13 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { // If not matched, we assume that its TLS. tlsl := tcpm.Match(cmux.Any()) - tlsConfig := tls.Config{} + tlsConfig := tls.Config{ + // Advertise that we support both http/1.1 and http2 for application level communication. + // By putting http/1.1 first, we ensure that HTTPS clients will use http/1.1, which is the only + // protocol our server supports for HTTPS clients. By including h2 in the list, we ensure that + // gRPC clients know we support http2 for their communication. + NextProtos: []string{"http/1.1", "h2"}, + } tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { return a.settings.Certificate, nil } @@ -595,35 +628,118 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { log.Fatal("Timed out waiting for project cache to sync") } - a.stopCh = make(chan struct{}) - <-a.stopCh + shutdownFunc := func() { + log.Info("API Server shutdown initiated. Shutting down servers...") + a.available.Store(false) + shutdownCtx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + var wg gosync.WaitGroup + + // Shutdown http server + wg.Add(1) + go func() { + defer wg.Done() + err := httpS.Shutdown(shutdownCtx) + if err != nil { + log.Errorf("Error shutting down http server: %s", err) + } + }() + + if a.useTLS() { + // Shutdown https server + wg.Add(1) + go func() { + defer wg.Done() + err := httpsS.Shutdown(shutdownCtx) + if err != nil { + log.Errorf("Error shutting down https server: %s", err) + } + }() + } + + // Shutdown gRPC server + wg.Add(1) + go func() { + defer wg.Done() + grpcS.GracefulStop() + }() + + // Shutdown metrics server + wg.Add(1) + go func() { + defer wg.Done() + err := metricsServ.Shutdown(shutdownCtx) + if err != nil { + log.Errorf("Error shutting down metrics server: %s", err) + } + }() + + if a.useTLS() { + // Shutdown tls server + wg.Add(1) + go func() { + defer wg.Done() + tlsm.Close() + }() + } + + // Shutdown tcp server + wg.Add(1) + go func() { + defer wg.Done() + tcpm.Close() + }() + + c := make(chan struct{}) + // This goroutine will wait for all servers to conclude the shutdown + // process + go func() { + defer close(c) + wg.Wait() + }() + + select { + case <-c: + log.Info("All servers were gracefully shutdown. Exiting...") + case <-shutdownCtx.Done(): + log.Warn("Graceful shutdown timeout. Exiting...") + } + } + a.shutdown = shutdownFunc + signal.Notify(a.stopCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + a.available.Store(true) + + select { + case signal := <-a.stopCh: + log.Infof("API Server received signal: %s", signal.String()) + // SIGUSR1 is used for triggering a server restart + if signal != syscall.SIGUSR1 { + a.terminateRequested.Store(true) + } + a.shutdown() + case <-ctx.Done(): + log.Infof("API Server: %s", ctx.Err()) + a.terminateRequested.Store(true) + a.shutdown() + } } func (a *ArgoCDServer) Initialized() bool { return a.projInformer.HasSynced() && a.appInformer.HasSynced() } +// TerminateRequested returns whether a shutdown was initiated by a signal or context cancel +// as opposed to a watch. +func (a *ArgoCDServer) TerminateRequested() bool { + return a.terminateRequested.Load() +} + // checkServeErr checks the error from a .Serve() call to decide if it was a graceful shutdown func (a *ArgoCDServer) checkServeErr(name string, err error) { - if err != nil { - if a.stopCh == nil { - // a nil stopCh indicates a graceful shutdown - log.Infof("graceful shutdown %s: %v", name, err) - } else { - log.Fatalf("%s: %v", name, err) - } + if err != nil && !errors.Is(err, http.ErrServerClosed) { + log.Errorf("Error received from server %s: %v", name, err) } else { - log.Infof("graceful shutdown %s", name) - } -} - -// Shutdown stops the Argo CD server -func (a *ArgoCDServer) Shutdown() { - log.Info("Shut down requested") - stopCh := a.stopCh - a.stopCh = nil - if stopCh != nil { - close(stopCh) + log.Infof("Graceful shutdown of %s initiated", name) } } @@ -706,7 +822,7 @@ func (a *ArgoCDServer) watchSettings() { log.Infof("gogs secret modified. restarting") break } - if prevExtConfig != a.settings.ExtensionConfig { + if !reflect.DeepEqual(prevExtConfig, a.settings.ExtensionConfig) { prevExtConfig = a.settings.ExtensionConfig log.Infof("extensions configs modified. Updating proxy registry...") err := a.extensionManager.UpdateExtensionRegistry(a.settings) @@ -728,9 +844,10 @@ func (a *ArgoCDServer) watchSettings() { } } log.Info("shutting down settings watch") - a.Shutdown() a.settingsMgr.Unsubscribe(updateCh) close(updateCh) + // Triggers server restart + a.stopCh <- syscall.SIGUSR1 } func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { @@ -776,19 +893,24 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre ), } sensitiveMethods := map[string]bool{ - "/cluster.ClusterService/Create": true, - "/cluster.ClusterService/Update": true, - "/session.SessionService/Create": true, - "/account.AccountService/UpdatePassword": true, - "/gpgkey.GPGKeyService/CreateGnuPGPublicKey": true, - "/repository.RepositoryService/Create": true, - "/repository.RepositoryService/Update": true, - "/repository.RepositoryService/CreateRepository": true, - "/repository.RepositoryService/UpdateRepository": true, - "/repository.RepositoryService/ValidateAccess": true, - "/repocreds.RepoCredsService/CreateRepositoryCredentials": true, - "/repocreds.RepoCredsService/UpdateRepositoryCredentials": true, - "/application.ApplicationService/PatchResource": true, + "/cluster.ClusterService/Create": true, + "/cluster.ClusterService/Update": true, + "/session.SessionService/Create": true, + "/account.AccountService/UpdatePassword": true, + "/gpgkey.GPGKeyService/CreateGnuPGPublicKey": true, + "/repository.RepositoryService/Create": true, + "/repository.RepositoryService/Update": true, + "/repository.RepositoryService/CreateRepository": true, + "/repository.RepositoryService/UpdateRepository": true, + "/repository.RepositoryService/ValidateAccess": true, + "/repocreds.RepoCredsService/CreateRepositoryCredentials": true, + "/repocreds.RepoCredsService/UpdateRepositoryCredentials": true, + "/repository.RepositoryService/CreateWriteRepository": true, + "/repository.RepositoryService/UpdateWriteRepository": true, + "/repository.RepositoryService/ValidateWriteAccess": true, + "/repocreds.RepoCredsService/CreateWriteRepositoryCredentials": true, + "/repocreds.RepoCredsService/UpdateWriteRepositoryCredentials": true, + "/application.ApplicationService/PatchResource": true, // Remove from logs both because the contents are sensitive and because they may be very large. "/application.ApplicationService/GetManifestsWithFiles": true, } @@ -863,7 +985,7 @@ type ArgoCDServiceSet struct { func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { kubectl := kubeutil.NewKubectl() clusterService := cluster.NewServer(a.db, a.enf, a.Cache, kubectl) - repoService := repository.NewServer(a.RepoClientset, a.db, a.enf, a.Cache, a.appLister, a.projInformer, a.Namespace, a.settingsMgr) + repoService := repository.NewServer(a.RepoClientset, a.db, a.enf, a.Cache, a.appLister, a.projInformer, a.Namespace, a.settingsMgr, a.HydratorEnabled) repoCredsService := repocreds.NewServer(a.RepoClientset, a.db, a.enf, a.settingsMgr) var loginRateLimiter func() (io.Closer, error) if maxConcurrentLoginRequestsCount > 0 { @@ -915,7 +1037,7 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db, a.EnableK8sEvent) appsInAnyNamespaceEnabled := len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0 - settingsService := settings.NewServer(a.settingsMgr, a.RepoClientset, a, a.DisableAuth, appsInAnyNamespaceEnabled) + settingsService := settings.NewServer(a.settingsMgr, a.RepoClientset, a, a.DisableAuth, appsInAnyNamespaceEnabled, a.HydratorEnabled) accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf) notificationService := notification.NewServer(a.apiFactory) @@ -1287,7 +1409,7 @@ func (server *ArgoCDServer) newStaticAssetsHandler() func(http.ResponseWriter, * w.Header().Set("X-XSS-Protection", "1") // serve index.html for non file requests to support HTML5 History API - if acceptHTML && !fileRequest && (r.Method == "GET" || r.Method == "HEAD") { + if acceptHTML && !fileRequest && (r.Method == http.MethodGet || r.Method == http.MethodHead) { for k, v := range noCacheHeaders { w.Header().Set(k, v) } diff --git a/server/server_test.go b/server/server_test.go index 7923db7f3e9d6..87a782b0fe245 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -10,6 +10,8 @@ import ( "os" "path/filepath" "strings" + gosync "sync" + "syscall" "testing" "time" @@ -51,9 +53,10 @@ type FakeArgoCDServer struct { } func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { + t.Helper() cm := test.NewFakeConfigMap() secret := test.NewFakeSecret() - kubeclientset := fake.NewSimpleClientset(cm, secret) + kubeclientset := fake.NewClientset(cm, secret) appClientSet := apps.NewSimpleClientset() redis, closer := test.NewInMemoryRedis() mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} @@ -122,7 +125,7 @@ func TestEnforceProjectToken(t *testing.T) { } cm := test.NewFakeConfigMap() secret := test.NewFakeSecret() - kubeclientset := fake.NewSimpleClientset(cm, secret) + kubeclientset := fake.NewClientset(cm, secret) mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} t.Run("TestEnforceProjectTokenSuccessful", func(t *testing.T) { @@ -201,7 +204,7 @@ func TestEnforceProjectToken(t *testing.T) { } func TestEnforceClaims(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap()) enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) rbacEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, test.NewFakeProjLister()) @@ -233,7 +236,7 @@ g, bob, role:admin } func TestDefaultRoleWithClaims(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) rbacEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, test.NewFakeProjLister()) @@ -247,7 +250,7 @@ func TestDefaultRoleWithClaims(t *testing.T) { } func TestEnforceNilClaims(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap()) enf := rbac.NewEnforcer(kubeclientset, test.FakeArgoCDNamespace, common.ArgoCDConfigMapName, nil) _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) rbacEnf := rbacpolicy.NewRBACPolicyEnforcer(enf, test.NewFakeProjLister()) @@ -260,7 +263,7 @@ func TestEnforceNilClaims(t *testing.T) { func TestInitializingExistingDefaultProject(t *testing.T) { cm := test.NewFakeConfigMap() secret := test.NewFakeSecret() - kubeclientset := fake.NewSimpleClientset(cm, secret) + kubeclientset := fake.NewClientset(cm, secret) defaultProj := &v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: v1alpha1.DefaultAppProjectName, Namespace: test.FakeArgoCDNamespace}, Spec: v1alpha1.AppProjectSpec{}, @@ -288,7 +291,7 @@ func TestInitializingExistingDefaultProject(t *testing.T) { func TestInitializingNotExistingDefaultProject(t *testing.T) { cm := test.NewFakeConfigMap() secret := test.NewFakeSecret() - kubeclientset := fake.NewSimpleClientset(cm, secret) + kubeclientset := fake.NewClientset(cm, secret) appClientSet := apps.NewSimpleClientset() mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} @@ -340,7 +343,7 @@ func TestEnforceProjectGroups(t *testing.T) { }, } mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}, ApplicationSetOpts{}) cancel := test.StartInformer(s.projInformer) defer cancel() @@ -374,7 +377,7 @@ func TestRevokedToken(t *testing.T) { defaultIssuedAt := int64(1) defaultSub := fmt.Sprintf(subFormat, projectName, roleName) defaultPolicy := fmt.Sprintf(policyTemplate, defaultSub, projectName, defaultObject, defaultEffect) - kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) + kubeclientset := fake.NewClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} jwtTokenByRole := make(map[string]v1alpha1.JWTTokens) @@ -418,6 +421,72 @@ func TestCertsAreNotGeneratedInInsecureMode(t *testing.T) { assert.Nil(t, s.settings.Certificate) } +func TestGracefulShutdown(t *testing.T) { + port, err := test.GetFreePort() + require.NoError(t, err) + mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} + kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) + redis, redisCloser := test.NewInMemoryRedis() + defer redisCloser() + s := NewServer( + context.Background(), + ArgoCDServerOpts{ + ListenPort: port, + Namespace: test.FakeArgoCDNamespace, + KubeClientset: kubeclientset, + AppClientset: apps.NewSimpleClientset(), + RepoClientset: mockRepoClient, + RedisClient: redis, + }, + ApplicationSetOpts{}, + ) + + projInformerCancel := test.StartInformer(s.projInformer) + defer projInformerCancel() + appInformerCancel := test.StartInformer(s.appInformer) + defer appInformerCancel() + appsetInformerCancel := test.StartInformer(s.appsetInformer) + defer appsetInformerCancel() + + lns, err := s.Listen() + require.NoError(t, err) + + shutdown := false + runCtx, runCancel := context.WithTimeout(context.Background(), 2*time.Second) + defer runCancel() + + err = s.healthCheck(&http.Request{URL: &url.URL{Path: "/healthz", RawQuery: "full=true"}}) + require.Error(t, err, "API Server is not running. It either hasn't started or is restarting.") + + var wg gosync.WaitGroup + wg.Add(1) + go func(shutdown *bool) { + defer wg.Done() + s.Run(runCtx, lns) + *shutdown = true + }(&shutdown) + + for { + if s.available.Load() { + err = s.healthCheck(&http.Request{URL: &url.URL{Path: "/healthz", RawQuery: "full=true"}}) + require.NoError(t, err) + break + } + time.Sleep(10 * time.Millisecond) + } + + s.stopCh <- syscall.SIGINT + + wg.Wait() + + err = s.healthCheck(&http.Request{URL: &url.URL{Path: "/healthz", RawQuery: "full=true"}}) + require.Error(t, err, "API Server is terminating and unable to serve requests.") + + assert.True(t, s.terminateRequested.Load()) + assert.False(t, s.available.Load()) + assert.True(t, shutdown) +} + func TestAuthenticate(t *testing.T) { type testData struct { test string @@ -477,6 +546,7 @@ func TestAuthenticate(t *testing.T) { } func dexMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { @@ -542,6 +612,7 @@ func dexMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Re } func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool, useDexForSSO bool, additionalOIDCConfig settings_util.OIDCConfig) (argocd *ArgoCDServer, oidcURL string) { + t.Helper() cm := test.NewFakeConfigMap() if anonymousEnabled { cm.Data["users.anonymous.enabled"] = "true" @@ -1355,7 +1426,7 @@ func TestCacheControlHeaders(t *testing.T) { name: "file exists", filename: "exists.html", createFile: true, - expectedStatus: 200, + expectedStatus: http.StatusOK, expectedCacheControlHeaders: nil, }, { @@ -1369,7 +1440,7 @@ func TestCacheControlHeaders(t *testing.T) { name: "main js bundle exists", filename: "main.e4188e5adc97bbfc00c3.js", createFile: true, - expectedStatus: 200, + expectedStatus: http.StatusOK, expectedCacheControlHeaders: []string{"public, max-age=31536000, immutable"}, }, { @@ -1532,9 +1603,10 @@ func TestReplaceBaseHRef(t *testing.T) { func Test_enforceContentTypes(t *testing.T) { getBaseHandler := func(t *testing.T, allow bool) http.Handler { + t.Helper() return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { assert.True(t, allow, "http handler was hit when it should have been blocked by content type enforcement") - writer.WriteHeader(200) + writer.WriteHeader(http.StatusOK) }) } @@ -1542,33 +1614,33 @@ func Test_enforceContentTypes(t *testing.T) { t.Run("GET - not providing a content type, should still succeed", func(t *testing.T) { handler := enforceContentTypes(getBaseHandler(t, true), []string{"application/json"}).(http.HandlerFunc) - req := httptest.NewRequest("GET", "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() handler(w, req) resp := w.Result() - assert.Equal(t, 200, resp.StatusCode) + assert.Equal(t, http.StatusOK, resp.StatusCode) }) t.Run("POST", func(t *testing.T) { handler := enforceContentTypes(getBaseHandler(t, true), []string{"application/json"}).(http.HandlerFunc) - req := httptest.NewRequest("POST", "/", nil) + req := httptest.NewRequest(http.MethodPost, "/", nil) w := httptest.NewRecorder() handler(w, req) resp := w.Result() - assert.Equal(t, 415, resp.StatusCode, "didn't provide a content type, should have gotten an error") + assert.Equal(t, http.StatusUnsupportedMediaType, resp.StatusCode, "didn't provide a content type, should have gotten an error") - req = httptest.NewRequest("POST", "/", nil) + req = httptest.NewRequest(http.MethodPost, "/", nil) req.Header = map[string][]string{"Content-Type": {"application/json"}} w = httptest.NewRecorder() handler(w, req) resp = w.Result() - assert.Equal(t, 200, resp.StatusCode, "should have passed, since an allowed content type was provided") + assert.Equal(t, http.StatusOK, resp.StatusCode, "should have passed, since an allowed content type was provided") - req = httptest.NewRequest("POST", "/", nil) + req = httptest.NewRequest(http.MethodPost, "/", nil) req.Header = map[string][]string{"Content-Type": {"not-allowed"}} w = httptest.NewRecorder() handler(w, req) resp = w.Result() - assert.Equal(t, 415, resp.StatusCode, "should not have passed, since a disallowed content type was provided") + assert.Equal(t, http.StatusUnsupportedMediaType, resp.StatusCode, "should not have passed, since a disallowed content type was provided") }) } diff --git a/server/settings/settings.go b/server/settings/settings.go index a598b5284f743..919ca89cc3f58 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -24,6 +24,7 @@ type Server struct { authenticator Authenticator disableAuth bool appsInAnyNamespaceEnabled bool + hydratorEnabled bool } type Authenticator interface { @@ -31,8 +32,8 @@ type Authenticator interface { } // NewServer returns a new instance of the Settings service -func NewServer(mgr *settings.SettingsManager, repoClient apiclient.Clientset, authenticator Authenticator, disableAuth, appsInAnyNamespaceEnabled bool) *Server { - return &Server{mgr: mgr, repoClient: repoClient, authenticator: authenticator, disableAuth: disableAuth, appsInAnyNamespaceEnabled: appsInAnyNamespaceEnabled} +func NewServer(mgr *settings.SettingsManager, repoClient apiclient.Clientset, authenticator Authenticator, disableAuth, appsInAnyNamespaceEnabled bool, hydratorEnabled bool) *Server { + return &Server{mgr: mgr, repoClient: repoClient, authenticator: authenticator, disableAuth: disableAuth, appsInAnyNamespaceEnabled: appsInAnyNamespaceEnabled, hydratorEnabled: hydratorEnabled} } // Get returns Argo CD settings @@ -90,6 +91,7 @@ func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settin set := settingspkg.Settings{ URL: argoCDSettings.URL, + AdditionalURLs: argoCDSettings.AdditionalURLs, AppLabelKey: appInstanceLabelKey, ResourceOverrides: overrides, StatusBadgeEnabled: argoCDSettings.StatusBadgeEnabled, @@ -113,6 +115,7 @@ func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settin ExecEnabled: argoCDSettings.ExecEnabled, AppsInAnyNamespaceEnabled: s.appsInAnyNamespaceEnabled, ImpersonationEnabled: argoCDSettings.ImpersonationEnabled, + HydratorEnabled: s.hydratorEnabled, } if sessionmgr.LoggedIn(ctx) || s.disableAuth { diff --git a/server/settings/settings.proto b/server/settings/settings.proto index 4b2396d5a22a4..c4e8f746d1584 100644 --- a/server/settings/settings.proto +++ b/server/settings/settings.proto @@ -43,6 +43,9 @@ message Settings { string controllerNamespace = 23; bool appsInAnyNamespaceEnabled = 24; bool impersonationEnabled = 25; + string installationID = 26; + repeated string additionalUrls = 27 [(gogoproto.customname) = "AdditionalURLs"]; + bool hydratorEnabled = 28; } message GoogleAnalyticsConfig { diff --git a/test/container/Dockerfile b/test/container/Dockerfile index ad22c720bbb81..17727f6d553eb 100644 --- a/test/container/Dockerfile +++ b/test/container/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/redis:7.4.0@sha256:eadf354977d428e347d93046bb1a5569d701e8deb68f090215534a99dbcb23b9 as redis +FROM docker.io/library/redis:7.4.1@sha256:a06cea905344470eb49c972f3d030e22f28f632c1b4f43bbe4a26a4329dd6be5 as redis # There are libraries we will want to copy from here in the final stage of the # build, but the COPY directive does not have a way to determine system @@ -6,13 +6,13 @@ FROM docker.io/library/redis:7.4.0@sha256:eadf354977d428e347d93046bb1a5569d701e8 RUN ln -s /usr/lib/$(uname -m)-linux-gnu /usr/lib/linux-gnu # Please make sure to also check the contained yarn version and update the references below when upgrading this image's version -FROM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 as node +FROM docker.io/library/node:22.9.0@sha256:69e667a79aa41ec0db50bc452a60e705ca16f35285eaf037ebe627a65a5cdf52 as node -FROM docker.io/library/golang:1.23@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 as golang +FROM docker.io/library/golang:1.23.4@sha256:70031844b8c225351d0bb63e2c383f80db85d92ba894e3da7e13bcf80efa9a37 as golang FROM docker.io/library/registry:2.8@sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90 as registry -FROM docker.io/bitnami/kubectl:1.31@sha256:da4a9868e20d941636087cb8624a4bb441f5249d69e8f3d27e53c7d4d280a5f3 as kubectl +FROM docker.io/bitnami/kubectl:1.31@sha256:4d757d958f7f9c232a9aa4a1c8cc94fa2aa7a7a253869d7dce09b4dc58a3fbd6 as kubectl FROM docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 diff --git a/test/container/Procfile b/test/container/Procfile index 4cebac203f76d..5048fff289ed7 100644 --- a/test/container/Procfile +++ b/test/container/Procfile @@ -3,6 +3,7 @@ api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.41.1 serve /dex.yaml" redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}" repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}" +commit-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_BINARY_NAME=argocd-commit-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_COMMITSERVER_PORT:-8086}" ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start" reaper: ./test/container/reaper.sh sshd: sudo sh -c "test $ARGOCD_E2E_TEST = true && /usr/sbin/sshd -p 2222 -D -e" diff --git a/test/e2e/accounts_test.go b/test/e2e/accounts_test.go index 7f3f056a952c9..dd56837dacd22 100644 --- a/test/e2e/accounts_test.go +++ b/test/e2e/accounts_test.go @@ -120,9 +120,9 @@ func TestCreateAndUseAccountCLI(t *testing.T) { assert.Equal(t, `NAME ENABLED CAPABILITIES admin true login`, output) - SetAccounts(map[string][]string{ + errors.CheckError(SetAccounts(map[string][]string{ "test": {"login", "apiKey"}, - }) + })) output, err = RunCli("account", "list") errors.CheckError(err) diff --git a/test/e2e/app_deletion_test.go b/test/e2e/app_deletion_test.go index 9158dddffa06a..c0332eb017f98 100644 --- a/test/e2e/app_deletion_test.go +++ b/test/e2e/app_deletion_test.go @@ -9,6 +9,7 @@ import ( . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" ) // when a app gets stuck in sync, and we try to delete it, it won't delete, instead we must then terminate it @@ -16,11 +17,11 @@ import ( func TestDeletingAppStuckInSync(t *testing.T) { Given(t). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`, }, - }) + })) }). Async(true). Path("hook-custom-health"). @@ -58,7 +59,7 @@ func TestDeletingAppByLabel(t *testing.T) { // delete is unsuccessful since no selector match AndCLIOutput( func(output string, err error) { - assert.Contains(t, err.Error(), "no apps match selector foo=baz") + assert.ErrorContains(t, err, "no apps match selector foo=baz") }, ). When(). diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index d4717f57d0f7f..328d252f66703 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -91,8 +91,7 @@ func TestNamespacedGetLogsDenySwitchOn(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { _, err := RunCliWithRetry(5, "app", "logs", ctx.AppQualifiedName(), "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") - require.Error(t, err) - assert.Contains(t, err.Error(), "permission denied") + assert.ErrorContains(t, err, "permission denied") }) } @@ -347,7 +346,7 @@ func TestNamespacedAppCreationWithoutForceUpdate(t *testing.T) { }). When(). IgnoreErrors(). - CreateApp(). + CreateApp("--dest-server", KubernetesInternalAPIServerAddr). Then(). Expect(Error("", "existing application spec is different, use upsert flag to force update")) } @@ -667,8 +666,7 @@ func TestNamespacedAppWithSecrets(t *testing.T) { _, err = RunCli("app", "patch-resource", ctx.AppQualifiedName(), "--resource-name", "test-secret", "--kind", "Secret", "--patch", `{"op": "add", "path": "/data", "value": "hello"}'`, "--patch-type", "application/json-patch+json") - require.Error(t, err) - assert.Contains(t, err.Error(), fmt.Sprintf("failed to patch Secret %s/test-secret", DeploymentNamespace())) + require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", DeploymentNamespace())) assert.NotContains(t, err.Error(), "username") assert.NotContains(t, err.Error(), "password") @@ -854,14 +852,14 @@ func TestNamespacedKnownTypesInCRDDiffing(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). When(). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/Dummy": { KnownTypeFields: []KnownTypeField{{ Field: "spec", Type: "core/v1/ResourceList", }}, }, - }) + })) }). Refresh(RefreshTypeNormal). Then(). @@ -878,6 +876,7 @@ func TestNamespacedConfigMap(t *testing.T) { } func testNSEdgeCasesApplicationResources(t *testing.T, appPath string, statusCode health.HealthStatusCode, message ...string) { + t.Helper() ctx := Given(t) expect := ctx. Path(appPath). @@ -973,8 +972,7 @@ func TestNamespacedSyncResourceByLabel(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { _, err := RunCli("app", "sync", ctx.AppQualifiedName(), "--label", "this-label=does-not-exist") - require.Error(t, err) - assert.Contains(t, err.Error(), "level=fatal") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -1045,8 +1043,7 @@ func TestNamespacedNoLocalSyncWithAutosyncEnabled(t *testing.T) { require.NoError(t, err) _, err = RunCli("app", "sync", app.QualifiedName(), "--local", guestbookPathLocal) - require.Error(t, err) - assert.Contains(t, err.Error(), "Cannot use local sync") + assert.ErrorContains(t, err, "Cannot use local sync") }) } @@ -1089,12 +1086,12 @@ func TestNamespacedSyncAsync(t *testing.T) { // assertResourceActions verifies if view/modify resource actions are successful/failing for given application func assertNSResourceActions(t *testing.T, appName string, successful bool) { + t.Helper() assertError := func(err error, message string) { if successful { require.NoError(t, err) } else { - require.Error(t, err) - assert.Contains(t, err.Error(), message) + assert.ErrorContains(t, err, message) } } @@ -1254,7 +1251,7 @@ func TestNamespacedPermissionWithScopedRepo(t *testing.T) { When(). Create() - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Project(projName). @@ -1294,7 +1291,7 @@ func TestNamespacedPermissionDeniedWithScopedRepo(t *testing.T) { When(). Create() - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Create() @@ -1699,7 +1696,6 @@ func TestNamespacedCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) { CreateWithNoNameSpace(). Then(). And(func(app *Application) { - time.Sleep(500 * time.Millisecond) app, err := AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Empty(t, app.Status.Conditions) @@ -2236,14 +2232,14 @@ definitions: SetTrackingMethod("annotation"). Path("crd-subresource"). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/StatusSubResource": { Actions: actions, }, "argoproj.io/NonStatusSubResource": { Actions: actions, }, - }) + })) }). When().CreateApp().Sync().Then(). Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)). @@ -2324,14 +2320,14 @@ func TestNamespacedAppWaitOperationInProgress(t *testing.T) { SetAppNamespace(AppNamespace()). SetTrackingMethod("annotation"). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "batch/Job": { HealthLua: `return { status = 'Running' }`, }, "apps/Deployment": { HealthLua: `return { status = 'Suspended' }`, }, - }) + })) }). Async(true). Path("hook-and-deployment"). @@ -2442,14 +2438,14 @@ func TestNamespacedDisableManifestGeneration(t *testing.T) { }). When(). And(func() { - time.Sleep(3 * time.Second) - SetEnableManifestGeneration(map[ApplicationSourceType]bool{ + CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{ ApplicationSourceTypeKustomize: false, - }) + })) }). Refresh(RefreshTypeHard). Then(). And(func(app *Application) { + // Wait for refresh to complete time.Sleep(1 * time.Second) }). And(func(app *Application) { diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index 67e1b4b03397c..3b471bc304718 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -99,8 +99,7 @@ func TestGetLogsDenySwitchOn(t *testing.T) { Expect(HealthIs(health.HealthStatusHealthy)). And(func(app *Application) { _, err := RunCliWithRetry(appLogsRetryCount, "app", "logs", app.Name, "--kind", "Deployment", "--group", "", "--name", "guestbook-ui") - require.Error(t, err) - assert.Contains(t, err.Error(), "permission denied") + assert.ErrorContains(t, err, "permission denied") }) } @@ -196,7 +195,7 @@ func TestGetLogsAllowSwitchOff(t *testing.T) { }, }, "app-creator") - Given(t). + GivenWithSameState(t). Path("guestbook-logs"). When(). CreateApp(). @@ -450,7 +449,7 @@ func TestAppCreationWithoutForceUpdate(t *testing.T) { }). When(). IgnoreErrors(). - CreateApp(). + CreateApp("--dest-server", KubernetesInternalAPIServerAddr). Then(). Expect(Error("", "existing application spec is different, use upsert flag to force update")) } @@ -490,7 +489,7 @@ func TestPatchValuesObject(t *testing.T) { Expect(NoConditions()). And(func(app *Application) { // Check that the patch was a success. - assert.Equal(t, `{"some":{"foo":"bar","new":"field"}}`, string(app.Spec.Source.Helm.ValuesObject.Raw)) + assert.JSONEq(t, `{"some":{"foo":"bar","new":"field"}}`, string(app.Spec.Source.Helm.ValuesObject.Raw)) }) } @@ -758,6 +757,7 @@ func TestManipulateApplicationResources(t *testing.T) { } func assetSecretDataHidden(t *testing.T, manifest string) { + t.Helper() secret, err := UnmarshalToUnstructured(manifest) require.NoError(t, err) @@ -818,8 +818,7 @@ func TestAppWithSecrets(t *testing.T) { _, err = RunCli("app", "patch-resource", "test-app-with-secrets", "--resource-name", "test-secret", "--kind", "Secret", "--patch", `{"op": "add", "path": "/data", "value": "hello"}'`, "--patch-type", "application/json-patch+json") - require.Error(t, err) - assert.Contains(t, err.Error(), fmt.Sprintf("failed to patch Secret %s/test-secret", DeploymentNamespace())) + require.ErrorContains(t, err, fmt.Sprintf("failed to patch Secret %s/test-secret", DeploymentNamespace())) assert.NotContains(t, err.Error(), "username") assert.NotContains(t, err.Error(), "password") @@ -999,14 +998,14 @@ func TestKnownTypesInCRDDiffing(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). When(). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/Dummy": { KnownTypeFields: []KnownTypeField{{ Field: "spec", Type: "core/v1/ResourceList", }}, }, - }) + })) }). Refresh(RefreshTypeNormal). Then(). @@ -1022,6 +1021,7 @@ func TestConfigMap(t *testing.T) { } func testEdgeCasesApplicationResources(t *testing.T, appPath string, statusCode health.HealthStatusCode, message ...string) { + t.Helper() expect := Given(t). Path(appPath). When(). @@ -1324,8 +1324,7 @@ func TestSyncResourceByLabel(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { _, err := RunCli("app", "sync", app.Name, "--label", "this-label=does-not-exist") - require.Error(t, err) - assert.Contains(t, err.Error(), "level=fatal") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -1342,8 +1341,7 @@ func TestSyncResourceByProject(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { _, err := RunCli("app", "sync", app.Name, "--project", "this-project-does-not-exist") - require.Error(t, err) - assert.Contains(t, err.Error(), "level=fatal") + assert.ErrorContains(t, err, "level=fatal") }) } @@ -1446,12 +1444,12 @@ func TestSyncAsync(t *testing.T) { // assertResourceActions verifies if view/modify resource actions are successful/failing for given application func assertResourceActions(t *testing.T, appName string, successful bool) { + t.Helper() assertError := func(err error, message string) { if successful { require.NoError(t, err) } else { - require.Error(t, err) - assert.Contains(t, err.Error(), message) + assert.ErrorContains(t, err, message) } } @@ -1521,7 +1519,7 @@ func TestPermissions(t *testing.T) { appCtx := Given(t) projName := "argo-project" projActions := projectFixture. - Given(t). + GivenWithSameState(t). Name(projName). When(). Create() @@ -1605,7 +1603,7 @@ func TestPermissionWithScopedRepo(t *testing.T) { Create(). AddSource("*") - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Project(projName). @@ -1642,7 +1640,7 @@ func TestPermissionDeniedWithScopedRepo(t *testing.T) { When(). Create() - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Create() @@ -1668,7 +1666,7 @@ func TestPermissionDeniedWithNegatedNamespace(t *testing.T) { When(). Create() - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Project(projName). @@ -1695,7 +1693,7 @@ func TestPermissionDeniedWithNegatedServer(t *testing.T) { When(). Create() - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(RepoURL(RepoURLTypeFile)). Project(projName). @@ -2109,7 +2107,6 @@ func TestCreateAppWithNoNameSpaceForGlobalResource(t *testing.T) { CreateWithNoNameSpace(). Then(). And(func(app *Application) { - time.Sleep(500 * time.Millisecond) app, err := AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).Get(context.Background(), app.Name, metav1.GetOptions{}) require.NoError(t, err) assert.Empty(t, app.Status.Conditions) @@ -2246,8 +2243,7 @@ func TestNamespaceAutoCreation(t *testing.T) { And(func(app *Application) { // Make sure the namespace we are about to update to does not exist _, err := Run("", "kubectl", "get", "namespace", updatedNamespace) - require.Error(t, err) - assert.Contains(t, err.Error(), "not found") + assert.ErrorContains(t, err, "not found") }). When(). AppSet("--dest-namespace", updatedNamespace). @@ -2364,14 +2360,14 @@ definitions: Given(t). Path("crd-subresource"). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "argoproj.io/StatusSubResource": { Actions: actions, }, "argoproj.io/NonStatusSubResource": { Actions: actions, }, - }) + })) }). When().CreateApp().Sync().Then(). Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeSynced)). @@ -2449,14 +2445,14 @@ func TestAppWaitOperationInProgress(t *testing.T) { ctx := Given(t) ctx. And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "batch/Job": { HealthLua: `return { status = 'Running' }`, }, "apps/Deployment": { HealthLua: `return { status = 'Suspended' }`, }, - }) + })) }). Async(true). Path("hook-and-deployment"). @@ -2558,13 +2554,14 @@ func TestDisableManifestGeneration(t *testing.T) { }). When(). And(func() { - SetEnableManifestGeneration(map[ApplicationSourceType]bool{ + CheckError(SetEnableManifestGeneration(map[ApplicationSourceType]bool{ ApplicationSourceTypeKustomize: false, - }) + })) }). Refresh(RefreshTypeHard). Then(). And(func(app *Application) { + // Wait for refresh to complete time.Sleep(1 * time.Second) }). And(func(app *Application) { @@ -2761,7 +2758,7 @@ func TestSwitchTrackingLabel(t *testing.T) { func TestAnnotationTrackingExtraResources(t *testing.T) { ctx := Given(t) - SetTrackingMethod(string(argo.TrackingMethodAnnotation)) + CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation))) ctx. Path("deployment"). When(). @@ -2923,3 +2920,84 @@ data: Expect(ResourceHealthWithNamespaceIs("ConfigMap", "yet-another-map", DeploymentNamespace(), health.HealthStatusHealthy)). Expect(ResourceSyncStatusWithNamespaceIs("ConfigMap", "yet-another-map", DeploymentNamespace(), SyncStatusCodeSynced)) } + +func TestInstallationID(t *testing.T) { + ctx := Given(t) + ctx. + SetTrackingMethod(string(argo.TrackingMethodAnnotation)). + And(func() { + _, err := fixture.KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create( + context.Background(), &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-configmap", + Annotations: map[string]string{ + common.AnnotationKeyAppInstance: fmt.Sprintf("%s:/ConfigMap:%s/test-configmap", ctx.AppName(), DeploymentNamespace()), + }, + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + }). + Path(guestbookPath). + Prune(false). + When().IgnoreErrors().CreateApp().Sync(). + Then().Expect(OperationPhaseIs(OperationSucceeded)).Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + And(func(app *Application) { + var cm *ResourceStatus + for i := range app.Status.Resources { + if app.Status.Resources[i].Kind == "ConfigMap" && app.Status.Resources[i].Name == "test-configmap" { + cm = &app.Status.Resources[i] + break + } + } + require.NotNil(t, cm) + assert.Equal(t, SyncStatusCodeOutOfSync, cm.Status) + }). + When().SetInstallationID("test").Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + And(func(app *Application) { + require.Len(t, app.Status.Resources, 2) + svc, err := fixture.KubeClientset.CoreV1().Services(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "test", svc.Annotations[common.AnnotationInstallationID]) + + deploy, err := fixture.KubeClientset.AppsV1().Deployments(DeploymentNamespace()).Get(context.Background(), "guestbook-ui", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "test", deploy.Annotations[common.AnnotationInstallationID]) + }) +} + +func TestDeletionConfirmation(t *testing.T) { + ctx := Given(t) + ctx. + And(func() { + _, err := fixture.KubeClientset.CoreV1().ConfigMaps(DeploymentNamespace()).Create( + context.Background(), &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-configmap", + Labels: map[string]string{ + common.LabelKeyAppInstance: ctx.AppName(), + }, + Annotations: map[string]string{ + AnnotationSyncOptions: "Prune=confirm", + }, + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + }). + Path(guestbookPath). + Async(true). + When(). + PatchFile("guestbook-ui-deployment.yaml", `[{ "op": "add", "path": "/metadata/annotations", "value": { "argocd.argoproj.io/sync-options": "Delete=confirm" }}]`). + CreateApp().Sync(). + Then().Expect(OperationPhaseIs(OperationRunning)). + When().ConfirmDeletion(). + Then().Expect(OperationPhaseIs(OperationSucceeded)). + When().Delete(true). + Then(). + And(func(app *Application) { + assert.NotNil(t, app.DeletionTimestamp) + }). + When().ConfirmDeletion(). + Then().Expect(DoesNotExist()) +} diff --git a/test/e2e/app_multiple_sources_test.go b/test/e2e/app_multiple_sources_test.go index fd5f2d8d5fb69..e3118244e18d0 100644 --- a/test/e2e/app_multiple_sources_test.go +++ b/test/e2e/app_multiple_sources_test.go @@ -167,3 +167,131 @@ func TestMultiSourceAppWithSourceOverride(t *testing.T) { assert.Contains(t, output, "foo=bar") }) } + +func TestMultiSourceAppWithSourceName(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + assert.Equal(t, sources[i].Name, source.Name) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + // we remove the first source + output, err := RunCli("app", "remove-source", Name(), "--source-name", sources[0].Name) + require.NoError(t, err) + assert.Contains(t, output, "updated successfully") + }). + Expect(Success("")). + And(func(app *Application) { + assert.Len(t, app.Spec.GetSources(), 1) + // we add a source + output, err := RunCli("app", "add-source", Name(), "--source-name", sources[0].Name, "--repo", RepoURL(RepoURLTypeFile), "--path", guestbookPath) + require.NoError(t, err) + assert.Contains(t, output, "updated successfully") + }). + Expect(Success("")). + Given().Timeout(60). + When().Wait().Then(). + Expect(Success("")). + And(func(app *Application) { + assert.Len(t, app.Spec.GetSources(), 2) + // sources order has been inverted + assert.Equal(t, sources[1].Name, app.Spec.GetSources()[0].Name) + assert.Equal(t, sources[0].Name, app.Spec.GetSources()[1].Name) + statusByName := map[string]SyncStatusCode{} + for _, r := range app.Status.Resources { + statusByName[r.Name] = r.Status + } + // check if the app has 3 resources, guestbook and 2 pods + assert.Len(t, statusByName, 3) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-1"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-2"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"]) + }) +} + +func TestMultiSourceAppSetWithSourceName(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + assert.Equal(t, sources[i].Name, source.Name) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + _, err := RunCli("app", "set", Name(), "--source-name", sources[1].Name, "--path", "deployment") + require.NoError(t, err) + }). + Expect(Success("")). + And(func(app *Application) { + assert.Equal(t, "deployment", app.Spec.GetSources()[1].Path) + }) +} + +func TestMultiSourceApptErrorWhenSourceNameAndSourcePosition(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + _, err := RunCli("app", "get", Name(), "--source-name", sources[1].Name, "--source-position", "1") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-position and source-name can be specified.") + }). + And(func(app *Application) { + _, err := RunCli("app", "manifests", Name(), "--revisions", "0.0.2", "--source-names", sources[0].Name, "--revisions", "0.0.2", "--source-positions", "1") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-positions and source-names can be specified.") + }) +} diff --git a/test/e2e/app_namespaces_test.go b/test/e2e/app_namespaces_test.go index 20e878a4685f1..d8195850f7727 100644 --- a/test/e2e/app_namespaces_test.go +++ b/test/e2e/app_namespaces_test.go @@ -77,11 +77,11 @@ func TestForbiddenNamespace(t *testing.T) { func TestDeletingNamespacedAppStuckInSync(t *testing.T) { ctx := Given(t) ctx.And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.annotations and obj.annotations['health'] or 'Progressing' }`, }, - }) + })) }). Async(true). SetAppNamespace(AppNamespace()). diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index 5df36d591b1d9..247fc3af2d40a 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -1,6 +1,7 @@ package e2e import ( + "context" "fmt" "io" "net" @@ -10,6 +11,8 @@ import ( "testing" "time" + "github.com/google/uuid" + corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -17,6 +20,7 @@ import ( "github.com/argoproj/pkg/rand" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" @@ -1401,7 +1405,6 @@ func TestSimpleGitDirectoryGeneratorGPGEnabledUnsignedCommits(t *testing.T) { } project := "gpg" - fixture.EnsureCleanState(t) Given(t). Project(project). When(). @@ -1720,7 +1723,6 @@ func TestSimpleGitFilesGeneratorGPGEnabledUnsignedCommits(t *testing.T) { generateExpectedApp("engineering-prod-guestbook"), } - fixture.EnsureCleanState(t) Given(t). Project(project). When(). @@ -1822,7 +1824,6 @@ func TestSimpleGitFilesGeneratorGPGEnabledWithoutKnownKeys(t *testing.T) { generateExpectedApp("engineering-prod-guestbook"), } - fixture.EnsureCleanState(t) Given(t). Project(project). Path(guestbookPath). @@ -2032,12 +2033,12 @@ func TestSimpleGitFilesPreserveResourcesOnDeletion(t *testing.T) { When(). Delete(). And(func() { - t.Log("Waiting 30 seconds to give the cluster a chance to delete the pods.") - // Wait 30 seconds to give the cluster a chance to deletes the pods, if it is going to do so. + t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") + // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. // It should NOT delete the pods; to do so would be an ApplicationSet bug, and // that is what we are testing here. - time.Sleep(30 * time.Second) - // The pod should continue to exist after 30 seconds. + time.Sleep(15 * time.Second) + // The pod should continue to exist after 15 seconds. }).Then().Expect(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) } @@ -2093,16 +2094,17 @@ func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) { When(). Delete(). And(func() { - t.Log("Waiting 30 seconds to give the cluster a chance to delete the pods.") - // Wait 30 seconds to give the cluster a chance to deletes the pods, if it is going to do so. + t.Log("Waiting 15 seconds to give the cluster a chance to delete the pods.") + // Wait 15 seconds to give the cluster a chance to deletes the pods, if it is going to do so. // It should NOT delete the pods; to do so would be an ApplicationSet bug, and // that is what we are testing here. - time.Sleep(30 * time.Second) - // The pod should continue to exist after 30 seconds. + time.Sleep(15 * time.Second) + // The pod should continue to exist after 15 seconds. }).Then().Expect(Pod(func(p corev1.Pod) bool { return strings.Contains(p.Name, "guestbook-ui") })) } func githubSCMMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { @@ -2292,11 +2294,10 @@ func githubSCMMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) } func testServerWithPort(t *testing.T, port int, handler http.Handler) *httptest.Server { + t.Helper() // Use mocked API response to avoid rate-limiting. l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) - if err != nil { - t.Error(fmt.Errorf("Unable to start server %w", err)) - } + require.NoError(t, err, "Unable to start server") ts := httptest.NewUnstartedServer(handler) @@ -2669,6 +2670,7 @@ func TestCustomApplicationFinalizersGoTemplate(t *testing.T) { } func githubPullMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { @@ -2704,6 +2706,219 @@ func githubPullMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request } } +func TestSimpleSCMProviderGeneratorTokenRefStrictOk(t *testing.T) { + secretName := uuid.New().String() + + ts := testServerWithPort(t, 8341, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + githubSCMMockHandler(t)(w, r) + })) + + ts.Start() + defer ts.Close() + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "argo-cd-guestbook", + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "git@github.com:argoproj/argo-cd.git", + TargetRevision: "master", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + // Because you can't &"". + repoMatch := "argo-cd" + + Given(t). + And(func() { + _, err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: fixture.TestNamespace(), + Name: secretName, + Labels: map[string]string{ + common.LabelKeySecretType: common.LabelValueSecretTypeSCMCreds, + }, + }, + Data: map[string][]byte{ + "hello": []byte("world"), + }, + }, metav1.CreateOptions{}) + + assert.NoError(t, err) + }). + // Create an SCMProviderGenerator-based ApplicationSet + When().Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-scm-provider-generator-strict", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "{{ url }}", + TargetRevision: "{{ branch }}", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + SCMProvider: &v1alpha1.SCMProviderGenerator{ + Github: &v1alpha1.SCMProviderGeneratorGithub{ + Organization: "argoproj", + API: ts.URL, + TokenRef: &argov1alpha1.SecretRef{ + SecretName: secretName, + Key: "hello", + }, + }, + Filters: []v1alpha1.SCMProviderGeneratorFilter{ + { + RepositoryMatch: &repoMatch, + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). + When().And(func() { + err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) + assert.NoError(t, err) + }) +} + +func TestSimpleSCMProviderGeneratorTokenRefStrictKo(t *testing.T) { + secretName := uuid.New().String() + + ts := testServerWithPort(t, 8341, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + githubSCMMockHandler(t)(w, r) + })) + + ts.Start() + defer ts.Close() + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "argo-cd-guestbook", + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Labels: map[string]string{ + common.LabelKeyAppInstance: "simple-scm-provider-generator-strict-ko", + }, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "git@github.com:argoproj/argo-cd.git", + TargetRevision: "master", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + // Because you can't &"". + repoMatch := "argo-cd" + + Given(t). + And(func() { + _, err := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: fixture.TestNamespace(), + Name: secretName, + Labels: map[string]string{ + // Try to exfiltrate cluster secret + common.LabelKeySecretType: common.LabelValueSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + "hello": []byte("world"), + }, + }, metav1.CreateOptions{}) + + assert.NoError(t, err) + }). + // Create an SCMProviderGenerator-based ApplicationSet + When().Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-scm-provider-generator-strict-ko", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{ repository }}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "{{ url }}", + TargetRevision: "{{ branch }}", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + SCMProvider: &v1alpha1.SCMProviderGenerator{ + Github: &v1alpha1.SCMProviderGeneratorGithub{ + Organization: "argoproj", + API: ts.URL, + TokenRef: &argov1alpha1.SecretRef{ + SecretName: secretName, + Key: "hello", + }, + }, + Filters: []v1alpha1.SCMProviderGeneratorFilter{ + { + RepositoryMatch: &repoMatch, + }, + }, + }, + }, + }, + }, + }).Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})). + When(). + And(func() { + // app should be listed + output, err := fixture.RunCli("appset", "get", "simple-scm-provider-generator-strict-ko") + require.NoError(t, err) + assert.Contains(t, output, fmt.Sprintf("scm provider: error fetching Github token: secret %s/%s is not a valid SCM creds secret", fixture.TestNamespace(), secretName)) + err2 := utils.GetE2EFixtureK8sClient().KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{}) + assert.NoError(t, err2) + }) +} + func TestSimplePullRequestGenerator(t *testing.T) { ts := testServerWithPort(t, 8343, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { githubPullMockHandler(t)(w, r) diff --git a/test/e2e/cluster_generator_test.go b/test/e2e/cluster_generator_test.go index aa73e36aea796..558d5c9c84ef5 100644 --- a/test/e2e/cluster_generator_test.go +++ b/test/e2e/cluster_generator_test.go @@ -494,3 +494,107 @@ func TestSimpleClusterGeneratorDeletingCluster(t *testing.T) { When(). Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) } + +func TestClusterGeneratorWithFlatListMode(t *testing.T) { + expectedAppTemplate := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "flat-clusters", + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "helm-guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Name: "cluster1", + Namespace: fixture.TestNamespace(), + }, + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, + }, + }, + } + + expectedAppCluster1 := *expectedAppTemplate.DeepCopy() + expectedAppCluster1.Spec.Source.Helm = &argov1alpha1.ApplicationSourceHelm{ + Values: `clusters: + - name: cluster1 +`, + } + + expectedAppCluster2 := *expectedAppTemplate.DeepCopy() + expectedAppCluster2.Spec.Source.Helm = &argov1alpha1.ApplicationSourceHelm{ + Values: `clusters: + - name: cluster1 + - name: cluster2 +`, + } + + Given(t). + // Create a ClusterGenerator-based ApplicationSet + When(). + CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). + Create(v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "simple-cluster-generator", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "flat-clusters"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "helm-guestbook", + Helm: &argov1alpha1.ApplicationSourceHelm{ + Values: `clusters: +{{- range .clusters }} + - name: {{ .name }} +{{- end }} +`, + }, + }, + Destination: argov1alpha1.ApplicationDestination{ + Name: "cluster1", + Namespace: fixture.TestNamespace(), + }, + SyncPolicy: &argov1alpha1.SyncPolicy{ + Automated: &argov1alpha1.SyncPolicyAutomated{}, + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + Clusters: &v1alpha1.ClusterGenerator{ + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "argocd.argoproj.io/secret-type": "cluster", + }, + }, + FlatList: true, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc"). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster2})). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})) +} diff --git a/test/e2e/cluster_test.go b/test/e2e/cluster_test.go index d09df7d0cc812..eab0d49f6aeea 100644 --- a/test/e2e/cluster_test.go +++ b/test/e2e/cluster_test.go @@ -37,7 +37,7 @@ https://kubernetes.default.svc in-cluster %v Successful `, GetVe When(). CreateApp() - tries := 5 + tries := 25 for i := 0; i <= tries; i += 1 { clusterFixture.GivenWithSameState(t). When(). @@ -50,7 +50,7 @@ https://kubernetes.default.svc in-cluster %v Successful `, GetVe break } else if i < tries { // We retry with a simple backoff - time.Sleep(time.Duration(i+1) * time.Second) + time.Sleep(time.Duration(i+1) * 100 * time.Millisecond) } } assert.Equal(t, expected, last) @@ -90,7 +90,7 @@ func TestClusterAddPermissionDenied(t *testing.T) { Create(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) } @@ -255,7 +255,7 @@ func TestClusterDeleteDenied(t *testing.T) { DeleteByName(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) // Attempt to remove cluster creds by server @@ -269,7 +269,7 @@ func TestClusterDeleteDenied(t *testing.T) { DeleteByServer(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied") }) } @@ -308,19 +308,13 @@ func TestClusterDelete(t *testing.T) { // Check that RBAC is created _, err := fixture.Run("", "kubectl", "get", "serviceaccount", "argocd-manager", "-n", "kube-system") - if err != nil { - t.Errorf("Expected no error from not finding serviceaccount argocd-manager but got:\n%s", err.Error()) - } + require.NoError(t, err, "Expected no error from not finding serviceaccount argocd-manager") _, err = fixture.Run("", "kubectl", "get", "clusterrole", "argocd-manager-role") - if err != nil { - t.Errorf("Expected no error from not finding clusterrole argocd-manager-role but got:\n%s", err.Error()) - } + require.NoError(t, err, "Expected no error from not finding clusterrole argocd-manager-role") _, err = fixture.Run("", "kubectl", "get", "clusterrolebinding", "argocd-manager-role-binding") - if err != nil { - t.Errorf("Expected no error from not finding clusterrolebinding argocd-manager-role-binding but got:\n%s", err.Error()) - } + require.NoError(t, err, "Expected no error from not finding clusterrolebinding argocd-manager-role-binding") clstAction.DeleteByName(). Then(). @@ -330,17 +324,11 @@ func TestClusterDelete(t *testing.T) { // Check that RBAC is removed after delete output, err := fixture.Run("", "kubectl", "get", "serviceaccount", "argocd-manager", "-n", "kube-system") - if err == nil { - t.Errorf("Expected error from not finding serviceaccount argocd-manager but got:\n%s", output) - } + require.Error(t, err, "Expected error from not finding serviceaccount argocd-manager but got:\n%s", output) output, err = fixture.Run("", "kubectl", "get", "clusterrole", "argocd-manager-role") - if err == nil { - t.Errorf("Expected error from not finding clusterrole argocd-manager-role but got:\n%s", output) - } + require.Error(t, err, "Expected error from not finding clusterrole argocd-manager-role but got:\n%s", output) output, err = fixture.Run("", "kubectl", "get", "clusterrolebinding", "argocd-manager-role-binding") - if err == nil { - t.Errorf("Expected error from not finding clusterrolebinding argocd-manager-role-binding but got:\n%s", output) - } + assert.Error(t, err, "Expected error from not finding clusterrolebinding argocd-manager-role-binding but got:\n%s", output) } diff --git a/test/e2e/custom_tool_test.go b/test/e2e/custom_tool_test.go index d5433977afa3f..f9bfc014bb847 100644 --- a/test/e2e/custom_tool_test.go +++ b/test/e2e/custom_tool_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" . "github.com/argoproj/argo-cd/v2/util/errors" @@ -25,7 +26,7 @@ func TestCustomToolWithGitCreds(t *testing.T) { ctx. And(func() { go startCMPServer(t, "./testdata/cmp-gitcreds") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). CustomCACertAdded(). @@ -39,7 +40,12 @@ func TestCustomToolWithGitCreds(t *testing.T) { Then(). Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). - Expect(HealthIs(health.HealthStatusHealthy)) + Expect(HealthIs(health.HealthStatusHealthy)). + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}") + require.NoError(t, err) + assert.Equal(t, "argocd", output) + }) } // make sure we can echo back the Git creds @@ -48,7 +54,7 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) { ctx. And(func() { go startCMPServer(t, "./testdata/cmp-gitcredstemplate") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). CustomCACertAdded(). @@ -65,6 +71,11 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitAskpass}") + require.NoError(t, err) + assert.Equal(t, "argocd", output) + }). And(func(app *Application) { output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.GitUsername}") require.NoError(t, err) @@ -77,13 +88,72 @@ func TestCustomToolWithGitCredsTemplate(t *testing.T) { }) } +// make sure we can read the Git creds stored in a temporary file +func TestCustomToolWithSSHGitCreds(t *testing.T) { + ctx := Given(t) + // path does not matter, we ignore it + ctx. + And(func() { + go startCMPServer(t, "./testdata/cmp-gitsshcreds") + time.Sleep(100 * time.Millisecond) + t.Setenv("ARGOCD_BINARY_NAME", "argocd") + }). + // add the private repo with ssh credentials + CustomSSHKnownHostsAdded(). + SSHRepoURLAdded(true). + RepoURLType(fixture.RepoURLTypeSSH). + Path("cmp-gitsshcreds"). + When(). + CreateApp(). + Sync(). + Sync(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCommand}") + require.NoError(t, err) + assert.Regexp(t, `-i [^ ]+`, output, "test plugin expects $GIT_SSH_COMMAND to contain the option '-i '") + }). + And(func(app *Application) { + output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", Name(), "-o", "jsonpath={.metadata.annotations.GitSSHCredsFileSHA}") + require.NoError(t, err) + assert.Regexp(t, `\w+\s+[\/\w]+`, output, "git ssh credentials file should be able to be read, hashing the contents") + }) +} + +func TestCustomToolWithSSHGitCredsDisabled(t *testing.T) { + ctx := Given(t) + // path does not matter, we ignore it + ctx. + And(func() { + go startCMPServer(t, "./testdata/cmp-gitsshcreds-disable-provide") + time.Sleep(100 * time.Millisecond) + t.Setenv("ARGOCD_BINARY_NAME", "argocd") + }). + CustomCACertAdded(). + // add the private repo with ssh credentials + CustomSSHKnownHostsAdded(). + SSHRepoURLAdded(true). + RepoURLType(RepoURLTypeSSH). + Path("cmp-gitsshcreds"). + When(). + IgnoreErrors(). + CreateApp("--validate=false"). + Sync(). + Then(). + Expect(OperationPhaseIs(OperationError)). + Expect(SyncStatusIs(SyncStatusCodeUnknown)) +} + // make sure we can echo back the env func TestCustomToolWithEnv(t *testing.T) { ctx := Given(t) ctx. And(func() { go startCMPServer(t, "./testdata/cmp-fileName") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). // does not matter what the path is @@ -102,9 +172,6 @@ func TestCustomToolWithEnv(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(app *Application) { - time.Sleep(1 * time.Second) - }). And(func(app *Application) { output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") require.NoError(t, err) @@ -144,7 +211,7 @@ func TestCustomToolSyncAndDiffLocal(t *testing.T) { ctx. And(func() { go startCMPServer(t, "./testdata/cmp-kustomize") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). // does not matter what the path is @@ -156,9 +223,6 @@ func TestCustomToolSyncAndDiffLocal(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(app *Application) { - time.Sleep(1 * time.Second) - }). And(func(app *Application) { FailOnErr(RunCli("app", "sync", ctx.AppName(), "--local", appPath, "--local-repo-root", testdataPath)) }). @@ -168,6 +232,7 @@ func TestCustomToolSyncAndDiffLocal(t *testing.T) { } func startCMPServer(t *testing.T, configFile string) { + t.Helper() pluginSockFilePath := TmpDir + PluginSockFilePath t.Setenv("ARGOCD_BINARY_NAME", "argocd-cmp-server") // ARGOCD_PLUGINSOCKFILEPATH should be set as the same value as repo server env var @@ -186,7 +251,7 @@ func TestCMPDiscoverWithFileName(t *testing.T) { Given(t). And(func() { go startCMPServer(t, "./testdata/cmp-fileName") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path(pluginName + "/subdir"). @@ -204,7 +269,7 @@ func TestCMPDiscoverWithFindGlob(t *testing.T) { Given(t). And(func() { go startCMPServer(t, "./testdata/cmp-find-glob") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook"). @@ -222,7 +287,7 @@ func TestCMPDiscoverWithPluginName(t *testing.T) { Given(t). And(func() { go startCMPServer(t, "./testdata/cmp-find-glob") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook"). @@ -245,7 +310,7 @@ func TestCMPDiscoverWithFindCommandWithEnv(t *testing.T) { ctx. And(func() { go startCMPServer(t, "./testdata/cmp-find-command") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path(pluginName). @@ -256,9 +321,6 @@ func TestCMPDiscoverWithFindCommandWithEnv(t *testing.T) { Expect(OperationPhaseIs(OperationSucceeded)). Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)). - And(func(app *Application) { - time.Sleep(1 * time.Second) - }). And(func(app *Application) { output, err := Run("", "kubectl", "-n", DeploymentNamespace(), "get", "cm", ctx.AppName(), "-o", "jsonpath={.metadata.annotations.Bar}") require.NoError(t, err) @@ -288,7 +350,7 @@ func TestPruneResourceFromCMP(t *testing.T) { Given(t). And(func() { go startCMPServer(t, "./testdata/cmp-find-glob") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook"). @@ -311,7 +373,7 @@ func TestPreserveFileModeForCMP(t *testing.T) { Given(t). And(func() { go startCMPServer(t, "./testdata/cmp-preserve-file-mode") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("cmp-preserve-file-mode"). @@ -331,7 +393,7 @@ func TestCMPWithSymlinkPartialFiles(t *testing.T) { Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook-partial-symlink-files"). @@ -348,7 +410,7 @@ func TestCMPWithSymlinkFiles(t *testing.T) { Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook-symlink-files"). @@ -365,7 +427,7 @@ func TestCMPWithSymlinkFolder(t *testing.T) { Given(t, WithTestData("testdata2")). And(func() { go startCMPServer(t, "./testdata2/cmp-symlink") - time.Sleep(1 * time.Second) + time.Sleep(100 * time.Millisecond) t.Setenv("ARGOCD_BINARY_NAME", "argocd") }). Path("guestbook-symlink-folder"). diff --git a/test/e2e/deployment_test.go b/test/e2e/deployment_test.go index 083a2a60d9b3d..49ae9ad402968 100644 --- a/test/e2e/deployment_test.go +++ b/test/e2e/deployment_test.go @@ -13,11 +13,13 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/clientcmd" "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/clusterauth" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" @@ -52,7 +54,7 @@ func TestDeployment(t *testing.T) { func TestDeploymentWithAnnotationTrackingMode(t *testing.T) { ctx := Given(t) - SetTrackingMethod(string(argo.TrackingMethodAnnotation)) + errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodAnnotation))) ctx. Path("deployment"). When(). @@ -75,7 +77,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) { func TestDeploymentWithLabelTrackingMode(t *testing.T) { ctx := Given(t) - SetTrackingMethod(string(argo.TrackingMethodLabel)) + errors.CheckError(SetTrackingMethod(string(argo.TrackingMethodLabel))) ctx. Path("deployment"). When(). @@ -259,6 +261,7 @@ func buildArgoCDClusterSecret(secretName, secretNamespace, clusterName, clusterS // - username = name of Namespace the simulated user is able to deploy to // - clusterScopedSecrets = whether the Service Account is namespace-scoped or cluster-scoped. func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecrets bool) { + t.Helper() // Create a new Namespace for our simulated user ns := corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -308,10 +311,19 @@ func createNamespaceScopedUser(t *testing.T, username string, clusterScopedSecre _, err = KubeClientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(context.Background(), &roleBinding, metav1.CreateOptions{}) require.NoError(t, err) - // Retrieve the bearer token from the ServiceAccount - token, err := clusterauth.GetServiceAccountBearerToken(KubeClientset, ns.Name, serviceAccountName, time.Second*60) - require.NoError(t, err) - assert.NotEmpty(t, token) + var token string + + // Attempting to patch the ServiceAccount can intermittently fail with 'failed to patch serviceaccount "(...)" with bearer token secret: Operation cannot be fulfilled on serviceaccounts "(...)": the object has been modified; please apply your changes to the latest version and try again' + // We thus keep trying for up to 20 seconds. + waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 20*time.Second, true, func(context.Context) (done bool, err error) { + // Retrieve the bearer token from the ServiceAccount + token, err = clusterauth.GetServiceAccountBearerToken(KubeClientset, ns.Name, serviceAccountName, time.Second*60) + + // Success is no error and a real token, otherwise keep trying + return (err == nil && token != ""), nil + }) + require.NoError(t, waitErr) + require.NotEmpty(t, token) // In order to test a cluster-scoped Argo CD Cluster Secret, we may optionally grant the ServiceAccount read-all permissions at cluster scope. if clusterScopedSecrets { diff --git a/test/e2e/fixture/account/actions.go b/test/e2e/fixture/account/actions.go index f5708c5606a41..41b6b2a63bbd3 100644 --- a/test/e2e/fixture/account/actions.go +++ b/test/e2e/fixture/account/actions.go @@ -2,6 +2,7 @@ package project import ( "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // this implements the "when" part of given/when/then @@ -46,25 +47,25 @@ func (a *Actions) prepareSetPasswordArgs(account string) []string { } func (a *Actions) Create() *Actions { - fixture.SetAccounts(map[string][]string{ + errors.CheckError(fixture.SetAccounts(map[string][]string{ a.context.name: {"login"}, - }) + })) _, _ = fixture.RunCli(a.prepareSetPasswordArgs(a.context.name)...) return a } func (a *Actions) SetPermissions(permissions []fixture.ACL, roleName string) *Actions { - fixture.SetPermissions(permissions, a.context.name, roleName) + errors.CheckError(fixture.SetPermissions(permissions, a.context.name, roleName)) return a } func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions { - fixture.SetParamInSettingConfigMap(key, value) + errors.CheckError(fixture.SetParamInSettingConfigMap(key, value)) return a } func (a *Actions) Login() *Actions { - fixture.LoginAs(a.context.name) + errors.CheckError(fixture.LoginAs(a.context.name)) return a } diff --git a/test/e2e/fixture/account/context.go b/test/e2e/fixture/account/context.go index 507ca0bd07f2c..8013030a951bf 100644 --- a/test/e2e/fixture/account/context.go +++ b/test/e2e/fixture/account/context.go @@ -2,7 +2,6 @@ package project import ( "testing" - "time" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" "github.com/argoproj/argo-cd/v2/util/env" @@ -18,6 +17,7 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() fixture.EnsureCleanState(t) // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. @@ -45,7 +45,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } diff --git a/test/e2e/fixture/admin/context.go b/test/e2e/fixture/admin/context.go index aed58cb1a7b79..017407f0c9d71 100644 --- a/test/e2e/fixture/admin/context.go +++ b/test/e2e/fixture/admin/context.go @@ -16,11 +16,13 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() fixture.EnsureCleanState(t) return GivenWithSameState(t) } func GivenWithSameState(t *testing.T) *Context { + t.Helper() // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 20, 0, 180) diff --git a/test/e2e/fixture/app/actions.go b/test/e2e/fixture/app/actions.go index 1d013b6628963..ee623f73d424f 100644 --- a/test/e2e/fixture/app/actions.go +++ b/test/e2e/fixture/app/actions.go @@ -4,6 +4,8 @@ import ( "encoding/json" "fmt" "os" + "slices" + "strconv" log "github.com/sirupsen/logrus" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -222,10 +224,15 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string { a.context.t.Helper() args = append([]string{ "app", "create", a.context.AppQualifiedName(), - "--repo", fixture.RepoURL(a.context.repoURLType), }, args...) - if a.context.destName != "" { + if a.context.drySourceRevision != "" || a.context.drySourcePath != "" || a.context.syncSourcePath != "" || a.context.syncSourceBranch != "" || a.context.hydrateToBranch != "" { + args = append(args, "--dry-source-repo", fixture.RepoURL(a.context.repoURLType)) + } else { + args = append(args, "--repo", fixture.RepoURL(a.context.repoURLType)) + } + + if a.context.destName != "" && a.context.isDestServerInferred && !slices.Contains(args, "--dest-server") { args = append(args, "--dest-name", a.context.destName) } else { args = append(args, "--dest-server", a.context.destServer) @@ -234,6 +241,26 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string { args = append(args, "--path", a.context.path) } + if a.context.drySourceRevision != "" { + args = append(args, "--dry-source-revision", a.context.drySourceRevision) + } + + if a.context.drySourcePath != "" { + args = append(args, "--dry-source-path", a.context.drySourcePath) + } + + if a.context.syncSourceBranch != "" { + args = append(args, "--sync-source-branch", a.context.syncSourceBranch) + } + + if a.context.syncSourcePath != "" { + args = append(args, "--sync-source-path", a.context.syncSourcePath) + } + + if a.context.hydrateToBranch != "" { + args = append(args, "--hydrate-to-branch", a.context.hydrateToBranch) + } + if a.context.chart != "" { args = append(args, "--helm-chart", a.context.chart) } @@ -269,6 +296,12 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string { if a.context.helmSkipCrds { args = append(args, "--helm-skip-crds") } + if a.context.helmSkipSchemaValidation { + args = append(args, "--helm-skip-schema-validation") + } + if a.context.helmSkipTests { + args = append(args, "--helm-skip-tests") + } return args } @@ -342,7 +375,7 @@ func (a *Actions) Sync(args ...string) *Actions { if a.context.name != "" { args = append(args, a.context.AppQualifiedName()) } - args = append(args, "--timeout", fmt.Sprintf("%v", a.context.timeout)) + args = append(args, "--timeout", strconv.Itoa(a.context.timeout)) if a.context.async { args = append(args, "--async") @@ -382,6 +415,14 @@ func (a *Actions) Sync(args ...string) *Actions { return a } +func (a *Actions) ConfirmDeletion() *Actions { + a.context.t.Helper() + + a.runCli("app", "confirm-deletion", a.context.AppQualifiedName()) + + return a +} + func (a *Actions) TerminateOp() *Actions { a.context.t.Helper() a.runCli("app", "terminate-op", a.context.AppQualifiedName()) @@ -430,13 +471,13 @@ func (a *Actions) Wait(args ...string) *Actions { if a.context.name != "" { args = append(args, a.context.AppQualifiedName()) } - args = append(args, "--timeout", fmt.Sprintf("%v", a.context.timeout)) + args = append(args, "--timeout", strconv.Itoa(a.context.timeout)) a.runCli(args...) return a } func (a *Actions) SetParamInSettingConfigMap(key, value string) *Actions { - fixture.SetParamInSettingConfigMap(key, value) + errors.CheckError(fixture.SetParamInSettingConfigMap(key, value)) return a } @@ -465,11 +506,16 @@ func (a *Actions) verifyAction() { } func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions { - fixture.SetTrackingMethod(trackingMethod) + errors.CheckError(fixture.SetTrackingMethod(trackingMethod)) + return a +} + +func (a *Actions) SetInstallationID(installationID string) *Actions { + errors.CheckError(fixture.SetInstallationID(installationID)) return a } func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions { - fixture.SetTrackingLabel(trackingLabel) + errors.CheckError(fixture.SetTrackingLabel(trackingLabel)) return a } diff --git a/test/e2e/fixture/app/consequences.go b/test/e2e/fixture/app/consequences.go index 9ee99fec6ca6d..0aaed8500855b 100644 --- a/test/e2e/fixture/app/consequences.go +++ b/test/e2e/fixture/app/consequences.go @@ -25,8 +25,22 @@ func (c *Consequences) Expect(e Expectation) *Consequences { c.context.t.Helper() var message string var state state + sleepIntervals := []time.Duration{ + 10 * time.Millisecond, + 20 * time.Millisecond, + 50 * time.Millisecond, + 100 * time.Millisecond, + 200 * time.Millisecond, + 300 * time.Millisecond, + 500 * time.Millisecond, + 1 * time.Second, + } + sleepIntervalsIdx := -1 timeout := time.Duration(c.timeout) * time.Second - for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { + for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) { + if sleepIntervalsIdx < len(sleepIntervals)-1 { + sleepIntervalsIdx++ + } state, message = e(c) switch state { case succeeded: @@ -42,6 +56,31 @@ func (c *Consequences) Expect(e Expectation) *Consequences { return c } +// ExpectConsistently will continuously evaluate a condition, and it must be true each time it is evaluated, otherwise the test is failed. The condition will be repeatedly evaluated until 'expirationDuration' is met, waiting 'waitDuration' after each success. +func (c *Consequences) ExpectConsistently(e Expectation, waitDuration time.Duration, expirationDuration time.Duration) *Consequences { + // this invocation makes sure this func is not reported as the cause of the failure - we are a "test helper" + c.context.t.Helper() + + expiration := time.Now().Add(expirationDuration) + for time.Now().Before(expiration) { + state, message := e(c) + switch state { + case succeeded: + log.Infof("expectation succeeded: %s", message) + case failed: + c.context.t.Fatalf("failed expectation: %s", message) + return c + } + + // On condition success: wait, then retry + log.Infof("Expectation '%s' passes, repeating to ensure consistency", message) + time.Sleep(waitDuration) + } + + // If the condition never failed before expiring, it is a pass. + return c +} + func (c *Consequences) And(block func(app *Application)) *Consequences { c.context.t.Helper() block(c.app()) diff --git a/test/e2e/fixture/app/context.go b/test/e2e/fixture/app/context.go index 2225cac54c61d..b013f7fbd4bde 100644 --- a/test/e2e/fixture/app/context.go +++ b/test/e2e/fixture/app/context.go @@ -11,40 +11,49 @@ import ( "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/env" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/settings" ) -// this implements the "given" part of given/when/then +// Context implements the "given" part of given/when/then type Context struct { t *testing.T path string chart string repoURLType fixture.RepoURLType // seconds - timeout int - name string - appNamespace string - destServer string - destName string - env string - parameters []string - namePrefix string - nameSuffix string - resource string - prune bool - configManagementPlugin string - async bool - localPath string - project string - revision string - force bool - applyOutOfSyncOnly bool - directoryRecurse bool - replace bool - helmPassCredentials bool - helmSkipCrds bool - trackingMethod v1alpha1.TrackingMethod - sources []v1alpha1.ApplicationSource + timeout int + name string + appNamespace string + destServer string + destName string + isDestServerInferred bool + env string + parameters []string + namePrefix string + nameSuffix string + resource string + prune bool + configManagementPlugin string + async bool + localPath string + project string + revision string + force bool + applyOutOfSyncOnly bool + directoryRecurse bool + replace bool + helmPassCredentials bool + helmSkipCrds bool + helmSkipSchemaValidation bool + helmSkipTests bool + trackingMethod v1alpha1.TrackingMethod + sources []v1alpha1.ApplicationSource + drySourceRevision string + drySourcePath string + syncSourceBranch string + syncSourcePath string + hydrateToBranch string } type ContextArgs struct { @@ -52,23 +61,27 @@ type ContextArgs struct { } func Given(t *testing.T, opts ...fixture.TestOption) *Context { + t.Helper() fixture.EnsureCleanState(t, opts...) return GivenWithSameState(t) } func GivenWithNamespace(t *testing.T, namespace string) *Context { + t.Helper() ctx := Given(t) ctx.appNamespace = namespace return ctx } func GivenWithSameState(t *testing.T) *Context { - // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout + t.Helper() + // ARGOCD_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 20, 0, 180) return &Context{ t: t, destServer: v1alpha1.KubernetesInternalAPIServerAddr, + destName: "in-cluster", repoURLType: fixture.RepoURLTypeFile, name: fixture.Name(), timeout: timeout, @@ -100,7 +113,7 @@ func (c *Context) AppNamespace() string { func (c *Context) SetAppNamespace(namespace string) *Context { c.appNamespace = namespace - // fixture.SetParamInSettingConfigMap("application.resourceTrackingMethod", "annotation") + // errors.CheckError(fixture.SetParamInSettingConfigMap("application.resourceTrackingMethod", "annotation")) return c } @@ -207,7 +220,7 @@ func (c *Context) SSHCredentialsAdded() *Context { } func (c *Context) ProjectSpec(spec v1alpha1.AppProjectSpec) *Context { - fixture.SetProjectSpec(c.project, spec) + errors.CheckError(fixture.SetProjectSpec(c.project, spec)) return c } @@ -235,6 +248,31 @@ func (c *Context) Path(path string) *Context { return c } +func (c *Context) DrySourceRevision(revision string) *Context { + c.drySourceRevision = revision + return c +} + +func (c *Context) DrySourcePath(path string) *Context { + c.drySourcePath = path + return c +} + +func (c *Context) SyncSourceBranch(branch string) *Context { + c.syncSourceBranch = branch + return c +} + +func (c *Context) SyncSourcePath(path string) *Context { + c.syncSourcePath = path + return c +} + +func (c *Context) HydrateToBranch(branch string) *Context { + c.hydrateToBranch = branch + return c +} + func (c *Context) Recurse() *Context { c.directoryRecurse = true return c @@ -257,11 +295,13 @@ func (c *Context) Timeout(timeout int) *Context { func (c *Context) DestServer(destServer string) *Context { c.destServer = destServer + c.isDestServerInferred = false return c } func (c *Context) DestName(destName string) *Context { c.destName = destName + c.isDestServerInferred = true return c } @@ -292,12 +332,12 @@ func (c *Context) NameSuffix(nameSuffix string) *Context { } func (c *Context) ResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) *Context { - fixture.SetResourceOverrides(overrides) + errors.CheckError(fixture.SetResourceOverrides(overrides)) return c } func (c *Context) ResourceFilter(filter settings.ResourcesFilter) *Context { - fixture.SetResourceFilter(filter) + errors.CheckError(fixture.SetResourceFilter(filter)) return c } @@ -307,8 +347,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } @@ -357,8 +395,23 @@ func (c *Context) HelmSkipCrds() *Context { return c } +func (c *Context) HelmSkipSchemaValidation() *Context { + c.helmSkipSchemaValidation = true + return c +} + +func (c *Context) HelmSkipTests() *Context { + c.helmSkipTests = true + return c +} + func (c *Context) SetTrackingMethod(trackingMethod string) *Context { - fixture.SetTrackingMethod(trackingMethod) + errors.CheckError(fixture.SetTrackingMethod(trackingMethod)) + return c +} + +func (c *Context) SetInstallationID(installationID string) *Context { + errors.CheckError(fixture.SetInstallationID(installationID)) return c } diff --git a/test/e2e/fixture/applicationsets/actions.go b/test/e2e/fixture/applicationsets/actions.go index 1a5b214f75482..27adae8497d75 100644 --- a/test/e2e/fixture/applicationsets/actions.go +++ b/test/e2e/fixture/applicationsets/actions.go @@ -455,7 +455,21 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions { var mostRecentError error - for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { + sleepIntervals := []time.Duration{ + 10 * time.Millisecond, + 20 * time.Millisecond, + 50 * time.Millisecond, + 100 * time.Millisecond, + 200 * time.Millisecond, + 300 * time.Millisecond, + 500 * time.Millisecond, + 1 * time.Second, + } + sleepIntervalsIdx := -1 + for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) { + if sleepIntervalsIdx < len(sleepIntervals)-1 { + sleepIntervalsIdx++ + } appSet, err := a.get() mostRecentError = err if err == nil { diff --git a/test/e2e/fixture/applicationsets/consequences.go b/test/e2e/fixture/applicationsets/consequences.go index 3da461c1c9e5e..a8a9dc8dd34a7 100644 --- a/test/e2e/fixture/applicationsets/consequences.go +++ b/test/e2e/fixture/applicationsets/consequences.go @@ -31,7 +31,21 @@ func (c *Consequences) ExpectWithDuration(e Expectation, timeout time.Duration) c.context.t.Helper() var message string var state state - for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { + sleepIntervals := []time.Duration{ + 10 * time.Millisecond, + 20 * time.Millisecond, + 50 * time.Millisecond, + 100 * time.Millisecond, + 200 * time.Millisecond, + 300 * time.Millisecond, + 500 * time.Millisecond, + 1 * time.Second, + } + sleepIntervalsIdx := -1 + for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepIntervals[sleepIntervalsIdx]) { + if sleepIntervalsIdx < len(sleepIntervals)-1 { + sleepIntervalsIdx++ + } state, message = e(c) switch state { case succeeded: diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index daa2474ea01d5..a08e11c91cb32 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -21,13 +21,12 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() utils.EnsureCleanState(t) return &Context{t: t} } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index 1ff0fbbfd6137..571e8148a2979 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -14,6 +14,7 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/equality" + apierr "k8s.io/apimachinery/pkg/api/errors" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -106,39 +107,55 @@ func GetE2EFixtureK8sClient() *E2EFixtureK8sClient { // EnsureCleanSlate ensures that the Kubernetes resources on the cluster are in a 'clean' state, before a test is run. func EnsureCleanState(t *testing.T) { + t.Helper() start := time.Now() fixtureClient := GetE2EFixtureK8sClient() policy := v1.DeletePropagationForeground - // Delete the applicationset-e2e namespace, if it exists - err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), ApplicationsResourcesNamespace, v1.DeleteOptions{PropagationPolicy: &policy}) - if err != nil && !strings.Contains(err.Error(), "not found") { // 'not found' error is expected - CheckError(err) - } - - // Delete the argocd-e2e-external namespace, if it exists - err2 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace), v1.DeleteOptions{PropagationPolicy: &policy}) - if err2 != nil && !strings.Contains(err2.Error(), "not found") { // 'not found' error is expected - CheckError(err2) - } - - // Delete the argocd-e2e-external namespace, if it exists - err3 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace2), v1.DeleteOptions{PropagationPolicy: &policy}) - if err3 != nil && !strings.Contains(err3.Error(), "not found") { // 'not found' error is expected - CheckError(err3) - } - - // delete resources - // kubectl delete applicationsets --all - CheckError(fixtureClient.AppSetClientset.DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{})) - // kubectl delete apps --all - CheckError(fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{})) - - // kubectl delete secrets -l e2e.argoproj.io=true - CheckError(fixtureClient.KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: TestingLabel + "=true"})) + fixture.RunFunctionsInParallelAndCheckErrors(t, []func() error{ + func() error { + // Delete the applicationset-e2e namespace, if it exists + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), ApplicationsResourcesNamespace, v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected + return err + } + return nil + }, + func() error { + // Delete the argocd-e2e-external namespace, if it exists + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace), v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected + return err + } + return nil + }, + func() error { + // Delete the argocd-e2e-external namespace, if it exists + err := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace2), v1.DeleteOptions{PropagationPolicy: &policy}) + if err != nil && !apierr.IsNotFound(err) { // 'not found' error is expected + return err + } + return nil + }, + // delete resources + func() error { + // kubectl delete applicationsets --all + return fixtureClient.AppSetClientset.DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{}) + }, + func() error { + // kubectl delete apps --all + return fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{}) + }, + func() error { + // kubectl delete secrets -l e2e.argoproj.io=true + return fixtureClient.KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: TestingLabel + "=true"}) + }, + }) // First we wait up to 30 seconds for all the ApplicationSets to delete, but we don't fail if they don't. // Why? We want to give Argo CD time to delete the Application's child resources, before we remove the finalizers below. @@ -156,7 +173,7 @@ func EnsureCleanState(t *testing.T) { }, time.Now().Add(30*time.Second)) // Remove finalizers from Argo CD Application resources in the namespace - err = waitForSuccess(func() error { + err := waitForSuccess(func() error { appList, err := fixtureClient.AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).List(context.Background(), v1.ListOptions{}) if err != nil { return err @@ -182,7 +199,7 @@ func EnsureCleanState(t *testing.T) { FailOnErr(Run("", "mkdir", "-p", TmpDir)) // We can switch user and as result in previous state we will have non-admin user, this case should be reset - fixture.LoginAs("admin") + CheckError(fixture.LoginAs("admin")) log.WithFields(log.Fields{"duration": time.Since(start), "name": t.Name(), "id": id, "username": "admin", "password": "password"}).Info("clean state") } @@ -259,7 +276,7 @@ func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) erro msg = fmt.Sprintf("namespace '%s' still exists, after delete", namespace) } - if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { + if msg == "" && err != nil && apierr.IsNotFound(err) { // Success is an error containing 'applicationset-e2e' not found. return nil } @@ -277,6 +294,18 @@ func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) erro func waitForSuccess(condition func() error, expireTime time.Time) error { var mostRecentError error + sleepIntervals := []time.Duration{ + 10 * time.Millisecond, + 20 * time.Millisecond, + 50 * time.Millisecond, + 100 * time.Millisecond, + 200 * time.Millisecond, + 300 * time.Millisecond, + 500 * time.Millisecond, + 1 * time.Second, + } + sleepIntervalsIdx := -1 + for { if time.Now().After(expireTime) { break @@ -292,8 +321,11 @@ func waitForSuccess(condition func() error, expireTime time.Time) error { break } - // Wait 0.5 seconds on fail - time.Sleep(500 * time.Millisecond) + // Wait on fail + if sleepIntervalsIdx < len(sleepIntervals)-1 { + sleepIntervalsIdx++ + } + time.Sleep(sleepIntervals[sleepIntervalsIdx]) } return mostRecentError } @@ -366,6 +398,7 @@ func ToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { // // Note: This only applies to tests that use the GitHub API (different from GitHub's Git service) func IsGitHubAPISkippedTest(t *testing.T) bool { + t.Helper() if strings.TrimSpace(os.Getenv("GITHUB_TOKEN")) == "" { t.Skip("Skipping this test, as the GITHUB_TOKEN is not set. Please ensure this test passes locally, with your own GITHUB_TOKEN.") return true diff --git a/test/e2e/fixture/cluster/context.go b/test/e2e/fixture/cluster/context.go index bd0102f891d71..7ac01134f2f4b 100644 --- a/test/e2e/fixture/cluster/context.go +++ b/test/e2e/fixture/cluster/context.go @@ -2,7 +2,6 @@ package cluster import ( "testing" - "time" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" "github.com/argoproj/argo-cd/v2/util/env" @@ -22,11 +21,13 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() fixture.EnsureCleanState(t) return GivenWithSameState(t) } func GivenWithSameState(t *testing.T) *Context { + t.Helper() // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 10, 0, 180) @@ -58,8 +59,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go index 24d0e4ce74d71..03863a5ef53a0 100644 --- a/test/e2e/fixture/fixture.go +++ b/test/e2e/fixture/fixture.go @@ -8,12 +8,12 @@ import ( "os" "path" "path/filepath" + "reflect" "strconv" "strings" "testing" "time" - "github.com/argoproj/pkg/errors" jsonpatch "github.com/evanphx/json-patch" log "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -46,6 +46,9 @@ const ( ArgoCDNamespace = "argocd-e2e" ArgoCDAppNamespace = "argocd-e2e-external" + // notifications controller, metrics server port + defaultNotificationServer = "localhost:9001" + // ensure all repos are in one directory tree, so we can easily clean them up TmpDir = "/tmp/argo-e2e" repoDir = "testdata.git" @@ -203,7 +206,7 @@ func init() { plainText = !tlsTestResult.TLS - LoginAs(adminUsername) + CheckError(LoginAs(adminUsername)) log.WithFields(log.Fields{"apiServerAddress": apiServerAddress}).Info("initialized") @@ -233,13 +236,25 @@ func init() { } } -func loginAs(username, password string) { +func loginAs(username, password string) error { closer, client, err := ArgoCDClientset.NewSessionClient() - CheckError(err) + if err != nil { + return err + } defer io.Close(closer) + userInfoResponse, err := client.GetUserInfo(context.Background(), &sessionpkg.GetUserInfoRequest{}) + if err != nil { + return err + } + if userInfoResponse.Username == username && userInfoResponse.LoggedIn { + return nil + } + sessionResponse, err := client.Create(context.Background(), &sessionpkg.SessionCreateRequest{Username: username, Password: password}) - CheckError(err) + if err != nil { + return err + } token = sessionResponse.Token ArgoCDClientset, err = apiclient.NewClient(&apiclient.ClientOptions{ @@ -253,15 +268,15 @@ func loginAs(username, password string) { RepoServerName: argoCDRepoServerName, AppControllerName: argoCDAppControllerName, }) - CheckError(err) + return err } -func LoginAs(username string) { +func LoginAs(username string) error { password := DefaultTestUserPassword if username == "admin" { password = AdminPassword } - loginAs(username, password) + return loginAs(username, password) } func Name() string { @@ -351,34 +366,54 @@ func CreateSecret(username, password string) string { } // Convenience wrapper for updating argocd-cm -func updateSettingConfigMap(updater func(cm *corev1.ConfigMap) error) { - updateGenericConfigMap(common.ArgoCDConfigMapName, updater) +func updateSettingConfigMap(updater func(cm *corev1.ConfigMap) error) error { + return updateGenericConfigMap(common.ArgoCDConfigMapName, updater) } // Convenience wrapper for updating argocd-notifications-cm -func updateNotificationsConfigMap(updater func(cm *corev1.ConfigMap) error) { - updateGenericConfigMap(common.ArgoCDNotificationsConfigMapName, updater) +func updateNotificationsConfigMap(updater func(cm *corev1.ConfigMap) error) error { + return updateGenericConfigMap(common.ArgoCDNotificationsConfigMapName, updater) } // Convenience wrapper for updating argocd-cm-rbac -func updateRBACConfigMap(updater func(cm *corev1.ConfigMap) error) { - updateGenericConfigMap(common.ArgoCDRBACConfigMapName, updater) +func updateRBACConfigMap(updater func(cm *corev1.ConfigMap) error) error { + return updateGenericConfigMap(common.ArgoCDRBACConfigMapName, updater) +} + +func configMapsEquivalent(a *corev1.ConfigMap, b *corev1.ConfigMap) bool { + return reflect.DeepEqual(a.Immutable, b.Immutable) && + reflect.DeepEqual(a.TypeMeta, b.TypeMeta) && + reflect.DeepEqual(a.ObjectMeta, b.ObjectMeta) && + // Covers cases when one map is nil and another is empty map + (len(a.Data) == 0 && len(b.Data) == 0 || reflect.DeepEqual(a.Data, b.Data)) && + (len(a.BinaryData) == 0 && len(b.BinaryData) == 0 || reflect.DeepEqual(a.BinaryData, b.BinaryData)) } // Updates a given config map in argocd-e2e namespace -func updateGenericConfigMap(name string, updater func(cm *corev1.ConfigMap) error) { +func updateGenericConfigMap(name string, updater func(cm *corev1.ConfigMap) error) error { cm, err := KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Get(context.Background(), name, v1.GetOptions{}) - errors.CheckError(err) + if err != nil { + return err + } + oldCm := cm.DeepCopy() if cm.Data == nil { cm.Data = make(map[string]string) } - errors.CheckError(updater(cm)) - _, err = KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Update(context.Background(), cm, v1.UpdateOptions{}) - errors.CheckError(err) + err = updater(cm) + if err != nil { + return err + } + if !configMapsEquivalent(cm, oldCm) { + _, err = KubeClientset.CoreV1().ConfigMaps(TestNamespace()).Update(context.Background(), cm, v1.UpdateOptions{}) + if err != nil { + return err + } + } + return nil } -func SetEnableManifestGeneration(val map[v1alpha1.ApplicationSourceType]bool) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetEnableManifestGeneration(val map[v1alpha1.ApplicationSourceType]bool) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range val { cm.Data[fmt.Sprintf("%s.enable", strings.ToLower(string(k)))] = strconv.FormatBool(v) } @@ -386,8 +421,8 @@ func SetEnableManifestGeneration(val map[v1alpha1.ApplicationSourceType]bool) { }) } -func SetResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) error { + err := updateSettingConfigMap(func(cm *corev1.ConfigMap) error { if len(overrides) > 0 { yamlBytes, err := yaml.Marshal(overrides) if err != nil { @@ -399,26 +434,36 @@ func SetResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) { } return nil }) + if err != nil { + return err + } + + return SetResourceOverridesSplitKeys(overrides) +} - SetResourceOverridesSplitKeys(overrides) +func SetInstallationID(installationID string) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { + cm.Data["installationID"] = installationID + return nil + }) } -func SetTrackingMethod(trackingMethod string) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetTrackingMethod(trackingMethod string) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { cm.Data["application.resourceTrackingMethod"] = trackingMethod return nil }) } -func SetTrackingLabel(trackingLabel string) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetTrackingLabel(trackingLabel string) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { cm.Data["application.instanceLabelKey"] = trackingLabel return nil }) } -func SetResourceOverridesSplitKeys(overrides map[string]v1alpha1.ResourceOverride) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetResourceOverridesSplitKeys(overrides map[string]v1alpha1.ResourceOverride) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range overrides { if v.HealthLua != "" { cm.Data[getResourceOverrideSplitKey(k, "health")] = v.HealthLua @@ -457,8 +502,8 @@ func getResourceOverrideSplitKey(key string, customizeType string) string { return fmt.Sprintf("resource.customizations.%s.%s", customizeType, groupKind) } -func SetAccounts(accounts map[string][]string) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetAccounts(accounts map[string][]string) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { for k, v := range accounts { cm.Data[fmt.Sprintf("accounts.%s", k)] = strings.Join(v, ",") } @@ -466,8 +511,8 @@ func SetAccounts(accounts map[string][]string) { }) } -func SetPermissions(permissions []ACL, username string, roleName string) { - updateRBACConfigMap(func(cm *corev1.ConfigMap) error { +func SetPermissions(permissions []ACL, username string, roleName string) error { + return updateRBACConfigMap(func(cm *corev1.ConfigMap) error { var aclstr string for _, permission := range permissions { @@ -481,8 +526,8 @@ func SetPermissions(permissions []ACL, username string, roleName string) { }) } -func SetResourceFilter(filters settings.ResourcesFilter) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetResourceFilter(filters settings.ResourcesFilter) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { exclusions, err := yaml.Marshal(filters.ResourceExclusions) if err != nil { return err @@ -497,8 +542,8 @@ func SetResourceFilter(filters settings.ResourcesFilter) { }) } -func SetHelmRepos(repos ...settings.HelmRepoCredentials) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetHelmRepos(repos ...settings.HelmRepoCredentials) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { yamlBytes, err := yaml.Marshal(repos) if err != nil { return err @@ -508,8 +553,8 @@ func SetHelmRepos(repos ...settings.HelmRepoCredentials) { }) } -func SetRepos(repos ...settings.RepositoryCredentials) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetRepos(repos ...settings.RepositoryCredentials) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { yamlBytes, err := yaml.Marshal(repos) if err != nil { return err @@ -519,23 +564,25 @@ func SetRepos(repos ...settings.RepositoryCredentials) { }) } -func SetProjectSpec(project string, spec v1alpha1.AppProjectSpec) { +func SetProjectSpec(project string, spec v1alpha1.AppProjectSpec) error { proj, err := AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, v1.GetOptions{}) - errors.CheckError(err) + if err != nil { + return err + } proj.Spec = spec _, err = AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, v1.UpdateOptions{}) - errors.CheckError(err) + return err } -func SetParamInSettingConfigMap(key, value string) { - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { +func SetParamInSettingConfigMap(key, value string) error { + return updateSettingConfigMap(func(cm *corev1.ConfigMap) error { cm.Data[key] = value return nil }) } -func SetParamInNotificationsConfigMap(key, value string) { - updateNotificationsConfigMap(func(cm *corev1.ConfigMap) error { +func SetParamInNotificationsConfigMap(key, value string) error { + return updateNotificationsConfigMap(func(cm *corev1.ConfigMap) error { cm.Data[key] = value return nil }) @@ -564,6 +611,7 @@ func WithTestData(testdata string) TestOption { } func EnsureCleanState(t *testing.T, opts ...TestOption) { + t.Helper() opt := newTestOption(opts...) // In large scenarios, we can skip tests that already run SkipIfAlreadyRun(t) @@ -573,158 +621,365 @@ func EnsureCleanState(t *testing.T, opts ...TestOption) { }) start := time.Now() - policy := v1.DeletePropagationBackground - // delete resources - // kubectl delete apps --all - CheckError(AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{})) - CheckError(AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).DeleteCollection(context.Background(), v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{})) - // kubectl delete appprojects --field-selector metadata.name!=default - CheckError(AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{FieldSelector: "metadata.name!=default"})) - // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-config - CheckError(KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepository})) - // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-creds - CheckError(KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds})) - // kubectl delete secrets -l argocd.argoproj.io/secret-type=cluster - CheckError(KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster})) - // kubectl delete secrets -l e2e.argoproj.io=true - CheckError(KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection(context.Background(), - v1.DeleteOptions{PropagationPolicy: &policy}, v1.ListOptions{LabelSelector: TestingLabel + "=true"})) - - FailOnErr(Run("", "kubectl", "delete", "ns", "-l", TestingLabel+"=true", "--field-selector", "status.phase=Active", "--wait=false")) - FailOnErr(Run("", "kubectl", "delete", "crd", "-l", TestingLabel+"=true", "--wait=false")) - FailOnErr(Run("", "kubectl", "delete", "clusterroles", "-l", TestingLabel+"=true", "--wait=false")) - - // reset settings - updateSettingConfigMap(func(cm *corev1.ConfigMap) error { - cm.Data = map[string]string{} - return nil - }) - - updateNotificationsConfigMap(func(cm *corev1.ConfigMap) error { - cm.Data = map[string]string{} - return nil - }) - // reset rbac - updateRBACConfigMap(func(cm *corev1.ConfigMap) error { - cm.Data = map[string]string{} - return nil + RunFunctionsInParallelAndCheckErrors(t, []func() error{ + func() error { + // kubectl delete apps ... + return AppClientset.ArgoprojV1alpha1().Applications(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{}) + }, + func() error { + // kubectl delete apps ... + return AppClientset.ArgoprojV1alpha1().Applications(AppNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{}) + }, + func() error { + // kubectl delete appprojects --field-selector metadata.name!=default + return AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{FieldSelector: "metadata.name!=default"}) + }, + func() error { + // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-config + return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepository}) + }, + func() error { + // kubectl delete secrets -l argocd.argoproj.io/secret-type=repo-creds + return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeRepoCreds}) + }, + func() error { + // kubectl delete secrets -l argocd.argoproj.io/secret-type=cluster + return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: common.LabelKeySecretType + "=" + common.LabelValueSecretTypeCluster}) + }, + func() error { + // kubectl delete secrets -l e2e.argoproj.io=true + return KubeClientset.CoreV1().Secrets(TestNamespace()).DeleteCollection( + context.Background(), + v1.DeleteOptions{PropagationPolicy: &policy}, + v1.ListOptions{LabelSelector: TestingLabel + "=true"}) + }, }) - // We can switch user and as result in previous state we will have non-admin user, this case should be reset - LoginAs(adminUsername) - - // reset gpg-keys config map - updateGenericConfigMap(common.ArgoCDGPGKeysConfigMapName, func(cm *corev1.ConfigMap) error { - cm.Data = map[string]string{} - return nil - }) + RunFunctionsInParallelAndCheckErrors(t, []func() error{ + func() error { + // delete old namespaces which were created by tests + namespaces, err := KubeClientset.CoreV1().Namespaces().List( + context.Background(), + v1.ListOptions{ + LabelSelector: TestingLabel + "=true", + FieldSelector: "status.phase=Active", + }, + ) + if err != nil { + return err + } + if len(namespaces.Items) > 0 { + args := []string{"delete", "ns", "--wait=false"} + for _, namespace := range namespaces.Items { + args = append(args, namespace.Name) + } + _, err := Run("", "kubectl", args...) + if err != nil { + return err + } + } - SetProjectSpec("default", v1alpha1.AppProjectSpec{ - OrphanedResources: nil, - SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, - ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, - SourceNamespaces: []string{AppNamespace()}, - }) + namespaces, err = KubeClientset.CoreV1().Namespaces().List(context.Background(), v1.ListOptions{}) + if err != nil { + return err + } + testNamespaceNames := []string{} + for _, namespace := range namespaces.Items { + if strings.HasPrefix(namespace.Name, E2ETestPrefix) { + testNamespaceNames = append(testNamespaceNames, namespace.Name) + } + } + if len(testNamespaceNames) > 0 { + args := []string{"delete", "ns"} + args = append(args, testNamespaceNames...) + _, err := Run("", "kubectl", args...) + if err != nil { + return err + } + } + return nil + }, + func() error { + // delete old CRDs which were created by tests, doesn't seem to have kube api to get items + _, err := Run("", "kubectl", "delete", "crd", "-l", TestingLabel+"=true", "--wait=false") + return err + }, + func() error { + // delete old ClusterRoles which were created by tests + clusterRoles, err := KubeClientset.RbacV1().ClusterRoles().List( + context.Background(), + v1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", TestingLabel, "true"), + }, + ) + if err != nil { + return err + } + if len(clusterRoles.Items) > 0 { + args := []string{"delete", "clusterrole", "--wait=false"} + for _, clusterRole := range clusterRoles.Items { + args = append(args, clusterRole.Name) + } + _, err := Run("", "kubectl", args...) + if err != nil { + return err + } + } - // Create separate project for testing gpg signature verification - FailOnErr(RunCli("proj", "create", "gpg")) - SetProjectSpec("gpg", v1alpha1.AppProjectSpec{ - OrphanedResources: nil, - SourceRepos: []string{"*"}, - Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, - ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, - SignatureKeys: []v1alpha1.SignatureKey{{KeyID: GpgGoodKeyID}}, - SourceNamespaces: []string{AppNamespace()}, + clusterRoles, err = KubeClientset.RbacV1().ClusterRoles().List(context.Background(), v1.ListOptions{}) + if err != nil { + return err + } + testClusterRoleNames := []string{} + for _, clusterRole := range clusterRoles.Items { + if strings.HasPrefix(clusterRole.Name, E2ETestPrefix) { + testClusterRoleNames = append(testClusterRoleNames, clusterRole.Name) + } + } + if len(testClusterRoleNames) > 0 { + args := []string{"delete", "clusterrole"} + args = append(args, testClusterRoleNames...) + _, err := Run("", "kubectl", args...) + if err != nil { + return err + } + } + return nil + }, + func() error { + // delete old ClusterRoleBindings which were created by tests + clusterRoleBindings, err := KubeClientset.RbacV1().ClusterRoleBindings().List(context.Background(), v1.ListOptions{}) + if err != nil { + return err + } + testClusterRoleBindingNames := []string{} + for _, clusterRoleBinding := range clusterRoleBindings.Items { + if strings.HasPrefix(clusterRoleBinding.Name, E2ETestPrefix) { + testClusterRoleBindingNames = append(testClusterRoleBindingNames, clusterRoleBinding.Name) + } + } + if len(testClusterRoleBindingNames) > 0 { + args := []string{"delete", "clusterrolebinding"} + args = append(args, testClusterRoleBindingNames...) + _, err := Run("", "kubectl", args...) + if err != nil { + return err + } + } + return nil + }, + func() error { + err := updateSettingConfigMap(func(cm *corev1.ConfigMap) error { + cm.Data = map[string]string{} + return nil + }) + if err != nil { + return err + } + err = updateNotificationsConfigMap(func(cm *corev1.ConfigMap) error { + cm.Data = map[string]string{} + return nil + }) + if err != nil { + return err + } + err = updateRBACConfigMap(func(cm *corev1.ConfigMap) error { + cm.Data = map[string]string{} + return nil + }) + if err != nil { + return err + } + return updateGenericConfigMap(common.ArgoCDGPGKeysConfigMapName, func(cm *corev1.ConfigMap) error { + cm.Data = map[string]string{} + return nil + }) + }, + func() error { + // We can switch user and as result in previous state we will have non-admin user, this case should be reset + return LoginAs(adminUsername) + }, }) - // Recreate temp dir - CheckError(os.RemoveAll(TmpDir)) - FailOnErr(Run("", "mkdir", "-p", TmpDir)) - - // random id - unique across test runs - randString, err := rand.String(5) - CheckError(err) - postFix := "-" + strings.ToLower(randString) - id = t.Name() + postFix - name = DnsFriendly(t.Name(), "") - deploymentNamespace = DnsFriendly(fmt.Sprintf("argocd-e2e-%s", t.Name()), postFix) - - // create TLS and SSH certificate directories - if IsLocal() { - FailOnErr(Run("", "mkdir", "-p", TmpDir+"/app/config/tls")) - FailOnErr(Run("", "mkdir", "-p", TmpDir+"/app/config/ssh")) - } - - // For signing during the tests - FailOnErr(Run("", "mkdir", "-p", TmpDir+"/gpg")) - FailOnErr(Run("", "chmod", "0700", TmpDir+"/gpg")) - prevGnuPGHome := os.Getenv("GNUPGHOME") - os.Setenv("GNUPGHOME", TmpDir+"/gpg") - // nolint:errcheck - Run("", "pkill", "-9", "gpg-agent") - FailOnErr(Run("", "gpg", "--import", "../fixture/gpg/signingkey.asc")) - os.Setenv("GNUPGHOME", prevGnuPGHome) - - // recreate GPG directories - if IsLocal() { - FailOnErr(Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/source")) - FailOnErr(Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/keys")) - FailOnErr(Run("", "chmod", "0700", TmpDir+"/app/config/gpg/keys")) - FailOnErr(Run("", "mkdir", "-p", TmpDir+PluginSockFilePath)) - FailOnErr(Run("", "chmod", "0700", TmpDir+PluginSockFilePath)) - } + RunFunctionsInParallelAndCheckErrors(t, []func() error{ + func() error { + err := SetProjectSpec("default", v1alpha1.AppProjectSpec{ + OrphanedResources: nil, + SourceRepos: []string{"*"}, + Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, + SourceNamespaces: []string{AppNamespace()}, + }) + if err != nil { + return err + } - // set-up tmp repo, must have unique name - FailOnErr(Run("", "cp", "-Rf", opt.testdata, repoDirectory())) - FailOnErr(Run(repoDirectory(), "chmod", "777", ".")) - FailOnErr(Run(repoDirectory(), "git", "init", "-b", "master")) - FailOnErr(Run(repoDirectory(), "git", "add", ".")) - FailOnErr(Run(repoDirectory(), "git", "commit", "-q", "-m", "initial commit")) + // Create separate project for testing gpg signature verification + _, err = AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Create( + context.Background(), + &v1alpha1.AppProject{ + ObjectMeta: v1.ObjectMeta{ + Name: "gpg", + }, + Spec: v1alpha1.AppProjectSpec{ + OrphanedResources: nil, + SourceRepos: []string{"*"}, + Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, + SignatureKeys: []v1alpha1.SignatureKey{{KeyID: GpgGoodKeyID}}, + SourceNamespaces: []string{AppNamespace()}, + }, + }, + v1.CreateOptions{}, + ) + return err + }, + func() error { + err := os.RemoveAll(TmpDir) + if err != nil { + return err + } + _, err = Run("", "mkdir", "-p", TmpDir) + if err != nil { + return err + } - if IsRemote() { - FailOnErr(Run(repoDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE"))) - FailOnErr(Run(repoDirectory(), "git", "push", "origin", "master", "-f")) - } + // create TLS and SSH certificate directories + if IsLocal() { + _, err = Run("", "mkdir", "-p", TmpDir+"/app/config/tls") + if err != nil { + return err + } + _, err = Run("", "mkdir", "-p", TmpDir+"/app/config/ssh") + if err != nil { + return err + } + } - // create namespace - FailOnErr(Run("", "kubectl", "create", "ns", DeploymentNamespace())) - FailOnErr(Run("", "kubectl", "label", "ns", DeploymentNamespace(), TestingLabel+"=true")) + // For signing during the tests + _, err = Run("", "mkdir", "-p", TmpDir+"/gpg") + if err != nil { + return err + } + _, err = Run("", "chmod", "0700", TmpDir+"/gpg") + if err != nil { + return err + } + prevGnuPGHome := os.Getenv("GNUPGHOME") + os.Setenv("GNUPGHOME", TmpDir+"/gpg") + // nolint:errcheck + Run("", "pkill", "-9", "gpg-agent") + _, err = Run("", "gpg", "--import", "../fixture/gpg/signingkey.asc") + if err != nil { + return err + } + os.Setenv("GNUPGHOME", prevGnuPGHome) - // delete old namespaces used by E2E tests - namespaces, err := KubeClientset.CoreV1().Namespaces().List(context.Background(), v1.ListOptions{}) - CheckError(err) - for _, namespace := range namespaces.Items { - if strings.HasPrefix(namespace.Name, E2ETestPrefix) { - FailOnErr(Run("", "kubectl", "delete", "ns", namespace.Name)) - } - } + // recreate GPG directories + if IsLocal() { + _, err = Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/source") + if err != nil { + return err + } + _, err = Run("", "mkdir", "-p", TmpDir+"/app/config/gpg/keys") + if err != nil { + return err + } + _, err = Run("", "chmod", "0700", TmpDir+"/app/config/gpg/keys") + if err != nil { + return err + } + _, err = Run("", "mkdir", "-p", TmpDir+PluginSockFilePath) + if err != nil { + return err + } + _, err = Run("", "chmod", "0700", TmpDir+PluginSockFilePath) + if err != nil { + return err + } + } - // delete old ClusterRoles that begin with "e2e-test-" prefix (E2ETestPrefix), which were created by tests - clusterRoles, err := KubeClientset.RbacV1().ClusterRoles().List(context.Background(), v1.ListOptions{}) - CheckError(err) - for _, clusterRole := range clusterRoles.Items { - if strings.HasPrefix(clusterRole.Name, E2ETestPrefix) { - FailOnErr(Run("", "kubectl", "delete", "clusterrole", clusterRole.Name)) - } - } + // set-up tmp repo, must have unique name + _, err = Run("", "cp", "-Rf", opt.testdata, repoDirectory()) + if err != nil { + return err + } + _, err = Run(repoDirectory(), "chmod", "777", ".") + if err != nil { + return err + } + _, err = Run(repoDirectory(), "git", "init", "-b", "master") + if err != nil { + return err + } + _, err = Run(repoDirectory(), "git", "add", ".") + if err != nil { + return err + } + _, err = Run(repoDirectory(), "git", "commit", "-q", "-m", "initial commit") + if err != nil { + return err + } - // delete old ClusterRoleBindings that begin with "e2e-test-prefix", which were created by E2E tests - clusterRoleBindings, err := KubeClientset.RbacV1().ClusterRoleBindings().List(context.Background(), v1.ListOptions{}) - CheckError(err) - for _, clusterRoleBinding := range clusterRoleBindings.Items { - if strings.HasPrefix(clusterRoleBinding.Name, E2ETestPrefix) { - FailOnErr(Run("", "kubectl", "delete", "clusterrolebinding", clusterRoleBinding.Name)) - } - } + if IsRemote() { + _, err = Run(repoDirectory(), "git", "remote", "add", "origin", os.Getenv("ARGOCD_E2E_GIT_SERVICE")) + if err != nil { + return err + } + _, err = Run(repoDirectory(), "git", "push", "origin", "master", "-f") + if err != nil { + return err + } + } + return nil + }, + func() error { + // random id - unique across test runs + randString, err := rand.String(5) + if err != nil { + return err + } + postFix := "-" + strings.ToLower(randString) + id = t.Name() + postFix + name = DnsFriendly(t.Name(), "") + deploymentNamespace = DnsFriendly(fmt.Sprintf("argocd-e2e-%s", t.Name()), postFix) + // create namespace + _, err = Run("", "kubectl", "create", "ns", DeploymentNamespace()) + if err != nil { + return err + } + _, err = Run("", "kubectl", "label", "ns", DeploymentNamespace(), TestingLabel+"=true") + return err + }, + }) - log.WithFields(log.Fields{"duration": time.Since(start), "name": t.Name(), "id": id, "username": "admin", "password": "password"}).Info("clean state") + log.WithFields(log.Fields{ + "duration": time.Since(start), + "name": t.Name(), + "id": id, + "username": "admin", + "password": "password", + }).Info("clean state") } func RunCliWithRetry(maxRetries int, args ...string) (string, error) { @@ -941,7 +1196,7 @@ func RestartRepoServer() { FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) // wait longer to avoid error on s390x - time.Sleep(10 * time.Second) + time.Sleep(5 * time.Second) } } @@ -974,6 +1229,7 @@ func LocalOrRemotePath(base string) string { // Environment variable names follow the ARGOCD_E2E_SKIP_ pattern, // and must be set to the string value 'true' in order to skip a test. func SkipOnEnv(t *testing.T, suffixes ...string) { + t.Helper() for _, suffix := range suffixes { e := os.Getenv("ARGOCD_E2E_SKIP_" + suffix) if e == "true" { @@ -985,6 +1241,7 @@ func SkipOnEnv(t *testing.T, suffixes ...string) { // SkipIfAlreadyRun skips a test if it has been already run by a previous // test cycle and was recorded. func SkipIfAlreadyRun(t *testing.T) { + t.Helper() if _, ok := testsRun[t.Name()]; ok { t.Skip() } @@ -993,6 +1250,7 @@ func SkipIfAlreadyRun(t *testing.T) { // RecordTestRun records a test that has been run successfully to a text file, // so that it can be automatically skipped if requested. func RecordTestRun(t *testing.T) { + t.Helper() if t.Skipped() || t.Failed() { return } @@ -1020,6 +1278,10 @@ func GetApiServerAddress() string { return apiServerAddress } +func GetNotificationServerAddress() string { + return defaultNotificationServer +} + func GetToken() string { return token } diff --git a/test/e2e/fixture/http.go b/test/e2e/fixture/http.go index 00c123ab5d893..68e674f9f8b36 100644 --- a/test/e2e/fixture/http.go +++ b/test/e2e/fixture/http.go @@ -12,13 +12,17 @@ import ( ) // DoHttpRequest executes a http request against the Argo CD API server -func DoHttpRequest(method string, path string, data ...byte) (*http.Response, error) { +func DoHttpRequest(method string, path string, host string, data ...byte) (*http.Response, error) { reqUrl, err := url.Parse(path) if err != nil { return nil, err } reqUrl.Scheme = "http" - reqUrl.Host = apiServerAddress + if host != "" { + reqUrl.Host = host + } else { + reqUrl.Host = apiServerAddress + } var body io.Reader if data != nil { body = bytes.NewReader(data) @@ -41,7 +45,7 @@ func DoHttpRequest(method string, path string, data ...byte) (*http.Response, er // DoHttpJsonRequest executes a http request against the Argo CD API server and unmarshals the response body as JSON func DoHttpJsonRequest(method string, path string, result interface{}, data ...byte) error { - resp, err := DoHttpRequest(method, path, data...) + resp, err := DoHttpRequest(method, path, "", data...) if err != nil { return err } diff --git a/test/e2e/fixture/notification/actions.go b/test/e2e/fixture/notification/actions.go index 4b3c328f7ed29..1012368ceeede 100644 --- a/test/e2e/fixture/notification/actions.go +++ b/test/e2e/fixture/notification/actions.go @@ -1,9 +1,8 @@ package notification import ( - "time" - "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) // this implements the "when" part of given/when/then @@ -12,16 +11,25 @@ import ( // using the Then() type Actions struct { context *Context + + healthy bool } func (a *Actions) SetParamInNotificationConfigMap(key, value string) *Actions { - fixture.SetParamInNotificationsConfigMap(key, value) + errors.CheckError(fixture.SetParamInNotificationsConfigMap(key, value)) return a } func (a *Actions) Then() *Consequences { a.context.t.Helper() - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Consequences{a.context, a} } + +func (a *Actions) Healthcheck() *Actions { + a.context.t.Helper() + _, err := fixture.DoHttpRequest("GET", + "/metrics", + fixture.GetNotificationServerAddress()) + a.healthy = err == nil + return a +} diff --git a/test/e2e/fixture/notification/consequences.go b/test/e2e/fixture/notification/consequences.go index bfc4b4b0e0988..46e09a4249327 100644 --- a/test/e2e/fixture/notification/consequences.go +++ b/test/e2e/fixture/notification/consequences.go @@ -19,6 +19,12 @@ func (c *Consequences) Services(block func(services *notification.ServiceList, e return c } +func (c *Consequences) Healthy(block func(healthy bool)) *Consequences { + c.context.t.Helper() + block(c.actions.healthy) + return c +} + func (c *Consequences) Triggers(block func(services *notification.TriggerList, err error)) *Consequences { c.context.t.Helper() block(c.listTriggers()) diff --git a/test/e2e/fixture/notification/context.go b/test/e2e/fixture/notification/context.go index 0b70362b0fb1a..3e257fcfff3f0 100644 --- a/test/e2e/fixture/notification/context.go +++ b/test/e2e/fixture/notification/context.go @@ -12,6 +12,7 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() fixture.EnsureCleanState(t) return &Context{t: t} } diff --git a/test/e2e/fixture/project/actions.go b/test/e2e/fixture/project/actions.go index 61a2ad90615fb..f4358366c847d 100644 --- a/test/e2e/fixture/project/actions.go +++ b/test/e2e/fixture/project/actions.go @@ -102,6 +102,6 @@ func (a *Actions) runCli(args ...string) { a.context.t.Helper() a.lastOutput, a.lastError = fixture.RunCli(args...) if !a.ignoreErrors { - require.Empty(a.context.t, a.lastError) + require.NoError(a.context.t, a.lastError) } } diff --git a/test/e2e/fixture/project/context.go b/test/e2e/fixture/project/context.go index e637acbba8cf4..8ab0a929f7ed0 100644 --- a/test/e2e/fixture/project/context.go +++ b/test/e2e/fixture/project/context.go @@ -2,7 +2,6 @@ package project import ( "testing" - "time" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" "github.com/argoproj/argo-cd/v2/util/env" @@ -20,11 +19,13 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() fixture.EnsureCleanState(t) return GivenWithSameState(t) } func GivenWithSameState(t *testing.T) *Context { + t.Helper() // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 10, 0, 180) @@ -61,7 +62,5 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } diff --git a/test/e2e/fixture/repos/context.go b/test/e2e/fixture/repos/context.go index 28064e721c5f4..0adea442fe9e5 100644 --- a/test/e2e/fixture/repos/context.go +++ b/test/e2e/fixture/repos/context.go @@ -2,7 +2,6 @@ package repos import ( "testing" - "time" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" "github.com/argoproj/argo-cd/v2/util/env" @@ -19,10 +18,16 @@ type Context struct { project string } -func Given(t *testing.T, sameState bool) *Context { - if !sameState { - fixture.EnsureCleanState(t) - } +func Given(t *testing.T) *Context { + t.Helper() + fixture.EnsureCleanState(t) + return GivenWithSameState(t) +} + +// GivenWithSameState skips cleaning state. Use this when you've already ensured you have a clean +// state in your test setup don't want to waste time by doing so again. +func GivenWithSameState(t *testing.T) *Context { + t.Helper() // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout // for any context. timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 10, 0, 180) @@ -49,8 +54,6 @@ func (c *Context) And(block func()) *Context { } func (c *Context) When() *Actions { - // in case any settings have changed, pause for 1s, not great, but fine - time.Sleep(1 * time.Second) return &Actions{context: c} } diff --git a/test/e2e/fixture/util.go b/test/e2e/fixture/util.go index f9ed39f15b3e9..0669440f681d5 100644 --- a/test/e2e/fixture/util.go +++ b/test/e2e/fixture/util.go @@ -3,6 +3,11 @@ package fixture import ( "regexp" "strings" + "testing" + + "github.com/argoproj/argo-cd/v2/util/errors" + + "golang.org/x/sync/errgroup" ) var ( @@ -21,3 +26,12 @@ func DnsFriendly(str string, postfix string) string { } return str + postfix } + +func RunFunctionsInParallelAndCheckErrors(t *testing.T, functions []func() error) { + t.Helper() + var eg errgroup.Group + for _, function := range functions { + eg.Go(function) + } + errors.CheckError(eg.Wait()) +} diff --git a/test/e2e/graceful_restart_test.go b/test/e2e/graceful_restart_test.go new file mode 100644 index 0000000000000..6f5c6960a4f1d --- /dev/null +++ b/test/e2e/graceful_restart_test.go @@ -0,0 +1,58 @@ +package e2e + +import ( + "context" + "net/http" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/argoproj/argo-cd/v2/pkg/apiclient/settings" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" +) + +func checkHealth(t *testing.T, requireHealthy bool) { + t.Helper() + resp, err := DoHttpRequest("GET", "/healthz?full=true", "") + if requireHealthy { + require.NoError(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + } else { + if err != nil { + if !strings.Contains(err.Error(), "connection refused") && !strings.Contains(err.Error(), "connection reset by peer") { + require.NoErrorf(t, err, "If an error returned, it must be about connection refused or reset by peer") + } + } else { + require.Contains(t, []int{http.StatusOK, http.StatusServiceUnavailable}, resp.StatusCode) + } + } +} + +func TestAPIServerGracefulRestart(t *testing.T) { + EnsureCleanState(t) + + // Should be healthy. + checkHealth(t, true) + // Should trigger API server restart. + errors.CheckError(fixture.SetParamInSettingConfigMap("url", "http://test-api-server-graceful-restart")) + + // Wait for ~5 seconds + for i := 0; i < 50; i++ { + checkHealth(t, false) + time.Sleep(100 * time.Millisecond) + } + // One final time, should be healthy, or restart is considered too slow for tests + checkHealth(t, true) + closer, settingsClient, err := ArgoCDClientset.NewSettingsClient() + if closer != nil { + defer closer.Close() + } + require.NoError(t, err) + settings, err := settingsClient.Get(context.Background(), &settings.SettingsQuery{}) + require.NoError(t, err) + require.Equal(t, "http://test-api-server-graceful-restart", settings.URL) +} diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index 9a95829c33c50..a893486811df5 100644 --- a/test/e2e/helm_test.go +++ b/test/e2e/helm_test.go @@ -501,6 +501,7 @@ func TestHelmWithDependenciesLegacyRepo(t *testing.T) { } func testHelmWithDependencies(t *testing.T, chartPath string, legacyRepo bool) { + t.Helper() ctx := Given(t). CustomCACertAdded(). // these are slow tests @@ -518,14 +519,14 @@ func testHelmWithDependencies(t *testing.T, chartPath string, legacyRepo bool) { FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Patch(context.Background(), "helm-repo", types.MergePatchType, []byte(`{"metadata": { "labels": {"e2e.argoproj.io": "true"} }}`), metav1.PatchOptions{})) - fixture.SetHelmRepos(settings.HelmRepoCredentials{ + CheckError(fixture.SetHelmRepos(settings.HelmRepoCredentials{ URL: RepoURL(RepoURLTypeHelm), Name: "custom-repo", KeySecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "keySecret"}, CertSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "certSecret"}, UsernameSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "username"}, PasswordSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "password"}, - }) + })) }) } else { ctx = ctx.HelmRepoAdded("custom-repo") diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go index 5fe2248051737..a538566986213 100644 --- a/test/e2e/hook_test.go +++ b/test/e2e/hook_test.go @@ -36,6 +36,7 @@ func TestPostSyncHookSuccessful(t *testing.T) { // make sure we can run a standard sync hook func testHookSuccessful(t *testing.T, hookType HookType) { + t.Helper() Given(t). Path("hook"). When(). @@ -334,7 +335,7 @@ func TestHookBeforeHookCreation(t *testing.T) { CheckError(err) assert.NotEmpty(t, creationTimestamp1) // pause to ensure that timestamp will change - time.Sleep(2 * time.Second) + time.Sleep(1 * time.Second) }). When(). Sync(). diff --git a/test/e2e/hydrator_test.go b/test/e2e/hydrator_test.go new file mode 100644 index 0000000000000..0d36aa240ad29 --- /dev/null +++ b/test/e2e/hydrator_test.go @@ -0,0 +1,102 @@ +package e2e + +import ( + "testing" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + + . "github.com/argoproj/gitops-engine/pkg/sync/common" +) + +func TestSimpleHydrator(t *testing.T) { + Given(t). + DrySourcePath("guestbook"). + DrySourceRevision("HEAD"). + SyncSourcePath("guestbook"). + SyncSourceBranch("env/test"). + When(). + CreateApp(). + Refresh(RefreshTypeNormal). + Wait("--hydrated"). + Sync(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)) +} + +func TestHydrateTo(t *testing.T) { + Given(t). + DrySourcePath("guestbook"). + DrySourceRevision("HEAD"). + SyncSourcePath("guestbook"). + SyncSourceBranch("env/test"). + HydrateToBranch("env/test-next"). + When(). + CreateApp(). + Refresh(RefreshTypeNormal). + Wait("--hydrated"). + Then(). + Given(). + // Async so we don't fail immediately on the error + Async(true). + When(). + Sync(). + Wait("--operation"). + Then(). + // Fails because we hydrated to env/test-next but not to env/test. + Expect(OperationPhaseIs(OperationError)). + When(). + // Will now hydrate to the sync source branch. + AppSet("--hydrate-to-branch", ""). + Refresh(RefreshTypeNormal). + Wait("--hydrated"). + Sync(). + Wait("--operation"). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)) +} + +func TestAddingApp(t *testing.T) { + // Make sure that if we add another app targeting the same sync branch, it hydrates correctly. + Given(t). + Name("test-adding-app-1"). + DrySourcePath("guestbook"). + DrySourceRevision("HEAD"). + SyncSourcePath("guestbook-1"). + SyncSourceBranch("env/test"). + When(). + CreateApp(). + Refresh(RefreshTypeNormal). + Wait("--hydrated"). + Sync(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Given(). + Name("test-adding-app-2"). + DrySourcePath("guestbook"). + DrySourceRevision("HEAD"). + SyncSourcePath("guestbook-2"). + SyncSourceBranch("env/test"). + When(). + CreateApp(). + Refresh(RefreshTypeNormal). + Wait("--hydrated"). + Sync(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + // Clean up the apps manually since we used custom names. + When(). + Delete(true). + Then(). + Expect(DoesNotExist()). + Given(). + Name("test-adding-app-1"). + When(). + Delete(true). + Then(). + Expect(DoesNotExist()) +} diff --git a/test/e2e/mask_secret_values_test.go b/test/e2e/mask_secret_values_test.go new file mode 100644 index 0000000000000..691cf2f7ec50e --- /dev/null +++ b/test/e2e/mask_secret_values_test.go @@ -0,0 +1,58 @@ +package e2e + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/gitops-engine/pkg/health" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" +) + +// Values of `.data` & `.stringData“ fields in Secret resources are masked in UI/CLI +// Optionally, values of `.metadata.annotations` can also be masked, if needed. +func TestMaskSecretValues(t *testing.T) { + sensitiveData := regexp.MustCompile(`SECRETVAL|NEWSECRETVAL|U0VDUkVUVkFM`) + + Given(t). + Path("empty-dir"). + When(). + SetParamInSettingConfigMap("resource.sensitive.mask.annotations", "token"). // hide sensitive annotation + AddFile("secrets.yaml", `apiVersion: v1 +kind: Secret +metadata: + name: secret + annotations: + token: SECRETVAL + app: test +stringData: + username: SECRETVAL +data: + password: U0VDUkVUVkFM +`). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + // sensitive data should be masked in manifests output + And(func(app *Application) { + mnfs, _ := RunCli("app", "manifests", app.Name) + assert.False(t, sensitiveData.MatchString(mnfs)) + }). + When(). + PatchFile("secrets.yaml", `[{"op": "replace", "path": "/stringData/username", "value": "NEWSECRETVAL"}]`). + PatchFile("secrets.yaml", `[{"op": "add", "path": "/metadata/annotations", "value": {"token": "NEWSECRETVAL"}}]`). + Refresh(RefreshTypeHard). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + // sensitive data should be masked in diff output + And(func(app *Application) { + diff, _ := RunCli("app", "diff", app.Name) + assert.False(t, sensitiveData.MatchString(diff)) + }) +} diff --git a/test/e2e/merge_e2e_test.go b/test/e2e/merge_e2e_test.go index 970996aee9819..95437b9f2892d 100644 --- a/test/e2e/merge_e2e_test.go +++ b/test/e2e/merge_e2e_test.go @@ -435,6 +435,7 @@ func TestMergeTerminalMergeGeneratorSelector(t *testing.T) { } func toAPIExtensionsJSON(t *testing.T, g interface{}) *apiextensionsv1.JSON { + t.Helper() resVal, err := json.Marshal(g) if err != nil { t.Error("unable to unmarshal json", g) diff --git a/test/e2e/multiarch-container/Dockerfile b/test/e2e/multiarch-container/Dockerfile index ad49d66dc585c..d023155785114 100644 --- a/test/e2e/multiarch-container/Dockerfile +++ b/test/e2e/multiarch-container/Dockerfile @@ -1,2 +1,2 @@ -FROM docker.io/library/busybox@sha256:c230832bd3b0be59a6c47ed64294f9ce71e91b327957920b6929a0caa8353140 +FROM docker.io/library/busybox@sha256:2919d0172f7524b2d8df9e50066a682669e6d170ac0f6a49676d54358fe970b5 CMD exec sh -c "trap : TERM INT; echo 'Hi' && tail -f /dev/null" diff --git a/test/e2e/notification_test.go b/test/e2e/notification_test.go index e4dd855a107e3..11ed412a39dca 100644 --- a/test/e2e/notification_test.go +++ b/test/e2e/notification_test.go @@ -40,3 +40,13 @@ func TestNotificationsListTriggers(t *testing.T) { assert.Equal(t, []*notification.Trigger{{Name: ptr.To("on-created")}}, triggers.Items) }) } + +func TestNotificationsHealthcheck(t *testing.T) { + ctx := notifFixture.Given(t) + ctx.When(). + Healthcheck(). + Then(). + Healthy(func(healthy bool) { + assert.True(t, healthy) + }) +} diff --git a/test/e2e/project_management_test.go b/test/e2e/project_management_test.go index f00c4e3eeba62..169227eea52a5 100644 --- a/test/e2e/project_management_test.go +++ b/test/e2e/project_management_test.go @@ -22,6 +22,7 @@ import ( ) func assertProjHasEvent(t *testing.T, a *v1alpha1.AppProject, message string, reason string) { + t.Helper() list, err := fixture.KubeClientset.CoreV1().Events(fixture.TestNamespace()).List(context.Background(), metav1.ListOptions{ FieldSelector: fields.SelectorFromSet(map[string]string{ "involvedObject.name": a.Name, @@ -147,38 +148,31 @@ func TestAddProjectDestination(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-destination", projectName, "https://192.168.99.100:8443", "test1", ) - if err != nil { - t.Fatalf("Unable to add project destination %v", err) - } + require.NoError(t, err, "Unable to add project destination") _, err = fixture.RunCli("proj", "add-destination", projectName, "https://192.168.99.100:8443", "test1", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "already defined") + require.ErrorContains(t, err, "already defined") _, err = fixture.RunCli("proj", "add-destination", projectName, "!*", "test1", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "server has an invalid format, '!*'") + require.ErrorContains(t, err, "server has an invalid format, '!*'") _, err = fixture.RunCli("proj", "add-destination", projectName, "https://192.168.99.100:8443", "!*", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "namespace has an invalid format, '!*'") + require.ErrorContains(t, err, "namespace has an invalid format, '!*'") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) @@ -196,18 +190,14 @@ func TestAddProjectDestinationWithName(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-destination", projectName, "in-cluster", "test1", "--name", ) - if err != nil { - t.Fatalf("Unable to add project destination %v", err) - } + require.NoError(t, err, "Unable to add project destination") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) @@ -233,29 +223,22 @@ func TestRemoveProjectDestination(t *testing.T) { }}, }, }, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "remove-destination", projectName, "https://192.168.99.100:8443", "test", ) - if err != nil { - t.Fatalf("Unable to remove project destination %v", err) - } + require.NoError(t, err, "Unable to remove project destination") _, err = fixture.RunCli("proj", "remove-destination", projectName, "https://192.168.99.100:8443", "test1", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "does not exist") + require.ErrorContains(t, err, "does not exist") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) - if err != nil { - t.Fatalf("Unable to get project %v", err) - } + require.NoError(t, err, "Unable to get project") assert.Equal(t, projectName, proj.Name) assert.Empty(t, proj.Spec.Destinations) assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) @@ -267,14 +250,10 @@ func TestAddProjectSource(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") - if err != nil { - t.Fatalf("Unable to add project source %v", err) - } + require.NoError(t, err, "Unable to add project source") _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") require.NoError(t, err) @@ -399,9 +378,7 @@ func TestAddOrphanedIgnore(t *testing.T) { projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName, "group", @@ -409,9 +386,7 @@ func TestAddOrphanedIgnore(t *testing.T) { "--name", "name", ) - if err != nil { - t.Fatalf("Unable to add resource to orphaned ignore %v", err) - } + require.NoError(t, err, "Unable to add resource to orphaned ignore") _, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName, "group", @@ -419,8 +394,7 @@ func TestAddOrphanedIgnore(t *testing.T) { "--name", "name", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "already defined") + require.ErrorContains(t, err, "already defined") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) @@ -446,9 +420,7 @@ func TestRemoveOrphanedIgnore(t *testing.T) { }, }, }, metav1.CreateOptions{}) - if err != nil { - t.Fatalf("Unable to create project %v", err) - } + require.NoError(t, err, "Unable to create project") _, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName, "group", @@ -456,9 +428,7 @@ func TestRemoveOrphanedIgnore(t *testing.T) { "--name", "name", ) - if err != nil { - t.Fatalf("Unable to remove resource from orphaned ignore list %v", err) - } + require.NoError(t, err, "Unable to remove resource from orphaned ignore list") _, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName, "group", @@ -466,13 +436,10 @@ func TestRemoveOrphanedIgnore(t *testing.T) { "--name", "name", ) - require.Error(t, err) - assert.Contains(t, err.Error(), "does not exist") + require.ErrorContains(t, err, "does not exist") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) - if err != nil { - t.Fatalf("Unable to get project %v", err) - } + require.NoError(t, err, "Unable to get project") assert.Equal(t, projectName, proj.Name) assert.Empty(t, proj.Spec.OrphanedResources.Ignore) assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) @@ -566,16 +533,12 @@ func TestGetVirtualProjectNoMatch(t *testing.T) { "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) require.NoError(t, err) - // Waiting for the app to be successfully created. - // Else the sync would fail to retrieve the app resources. - time.Sleep(time.Second * 2) - // App trying to sync a resource which is not blacked listed anywhere - _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) + _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10)) require.NoError(t, err) // app trying to sync a resource which is black listed by global project - _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) + _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10)) require.NoError(t, err) } @@ -606,16 +569,211 @@ func TestGetVirtualProjectMatch(t *testing.T) { "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) require.NoError(t, err) - // Waiting for the app to be successfully created. - // Else the sync would fail to retrieve the app resources. - time.Sleep(time.Second * 2) - // App trying to sync a resource which is not blacked listed anywhere - _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) - require.Error(t, err) - assert.Contains(t, err.Error(), "blocked by sync window") + _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", strconv.Itoa(10)) + require.ErrorContains(t, err, "blocked by sync window") // app trying to sync a resource which is black listed by global project - _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) - assert.Contains(t, err.Error(), "blocked by sync window") + _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", strconv.Itoa(10)) + assert.ErrorContains(t, err, "blocked by sync window") +} + +func TestAddProjectDestinationServiceAccount(t *testing.T) { + fixture.EnsureCleanState(t) + + projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( + context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) + require.NoError(t, err, "Unable to create project") + + // Given, an existing project + // When, a default destination service account with all valid fields is added to it, + // Then, there is no error. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "test-sa", + ) + require.NoError(t, err, "Unable to add project destination service account") + + // Given, an existing project + // When, a default destination service account with empty namespace is added to it, + // Then, there is no error. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "", + "test-sa", + ) + require.NoError(t, err, "Unable to add project destination service account") + + // Given, an existing project, + // When, a default destination service account is added with a custom service account namespace, + // Then, there is no error. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns1", + "test-sa", + "--service-account-namespace", + "default", + ) + require.NoError(t, err, "Unable to add project destination service account") + + // Given, an existing project, + // When, a duplicate default destination service account is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "test-sa", + ) + require.ErrorContains(t, err, "already defined") + + // Given, an existing project, + // When, a duplicate default destination service account is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "asdf", + ) + require.ErrorContains(t, err, "already added") + + // Given, an existing project, + // When, a default destination service account with negation glob pattern for server is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "!*", + "test-ns", + "test-sa", + ) + require.ErrorContains(t, err, "server has an invalid format, '!*'") + + // Given, an existing project, + // When, a default destination service account with negation glob pattern for server is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "!abc", + "test-ns", + "test-sa", + ) + require.ErrorContains(t, err, "server has an invalid format, '!abc'") + + // Given, an existing project, + // When, a default destination service account with negation glob pattern for namespace is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "!*", + "test-sa", + ) + require.ErrorContains(t, err, "namespace has an invalid format, '!*'") + + // Given, an existing project, + // When, a default destination service account with negation glob pattern for namespace is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "!abc", + "test-sa", + ) + require.ErrorContains(t, err, "namespace has an invalid format, '!abc'") + + // Given, an existing project, + // When, a default destination service account with empty service account is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, ''") + + // Given, an existing project, + // When, a default destination service account with service account having just white spaces is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + " ", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, ' '") + + // Given, an existing project, + // When, a default destination service account with service account having backwards slash char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "test\\sa", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, 'test\\\\sa'") + + // Given, an existing project, + // When, a default destination service account with service account having forward slash char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "test/sa", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, 'test/sa'") + + // Given, an existing project, + // When, a default destination service account with service account having square braces char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "[test-sa]", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, '[test-sa]'") + + // Given, an existing project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "test-ns", + "{test-sa}", + ) + require.ErrorContains(t, err, "defaultServiceAccount has an invalid format, '{test-sa}'") + + // Given, an existing project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "[[ech*", + "test-ns", + "test-sa", + ) + require.ErrorContains(t, err, "server has an invalid format, '[[ech*'") + + // Given, an existing project, + // When, a default destination service account with service account having curly braces char is added, + // Then, there is an error with appropriate message. + _, err = fixture.RunCli("proj", "add-destination-service-account", projectName, + "https://192.168.99.100:8443", + "[[ech*", + "test-sa", + ) + require.ErrorContains(t, err, "namespace has an invalid format, '[[ech*'") + + proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, projectName, proj.Name) + assert.Len(t, proj.Spec.DestinationServiceAccounts, 3) + + assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.DestinationServiceAccounts[0].Server) + assert.Equal(t, "test-ns", proj.Spec.DestinationServiceAccounts[0].Namespace) + assert.Equal(t, "test-sa", proj.Spec.DestinationServiceAccounts[0].DefaultServiceAccount) + + assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.DestinationServiceAccounts[1].Server) + assert.Equal(t, "", proj.Spec.DestinationServiceAccounts[1].Namespace) + assert.Equal(t, "test-sa", proj.Spec.DestinationServiceAccounts[1].DefaultServiceAccount) + + assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.DestinationServiceAccounts[2].Server) + assert.Equal(t, "test-ns1", proj.Spec.DestinationServiceAccounts[2].Namespace) + assert.Equal(t, "default:test-sa", proj.Spec.DestinationServiceAccounts[2].DefaultServiceAccount) + + assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) } diff --git a/test/e2e/repo_management_test.go b/test/e2e/repo_management_test.go index c49eb2eeba794..97627d84f31d8 100644 --- a/test/e2e/repo_management_test.go +++ b/test/e2e/repo_management_test.go @@ -89,7 +89,7 @@ func TestGetRepoWithInheritedCreds(t *testing.T) { func TestUpsertExistingRepo(t *testing.T) { app.Given(t).And(func() { - fixture.SetRepos(settings.RepositoryCredentials{URL: fixture.RepoURL(fixture.RepoURLTypeFile)}) + CheckError(fixture.SetRepos(settings.RepositoryCredentials{URL: fixture.RepoURL(fixture.RepoURLTypeFile)})) repoUrl := fixture.RepoURL(fixture.RepoURLTypeFile) _, err := fixture.RunCli("repo", "add", repoUrl) require.NoError(t, err) diff --git a/test/e2e/scoped_repository_test.go b/test/e2e/scoped_repository_test.go index d1da08b0a434d..0075b6bd1b40a 100644 --- a/test/e2e/scoped_repository_test.go +++ b/test/e2e/scoped_repository_test.go @@ -23,7 +23,7 @@ func TestCreateRepositoryWithProject(t *testing.T) { Then() path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(path). Project("argo-project"). @@ -48,7 +48,7 @@ func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) { Login() path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(path). Project("argo-project"). @@ -56,7 +56,7 @@ func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) { Create(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, create") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, create") }) } @@ -75,7 +75,7 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) { }, "org-admin") path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(path). Project("argo-project"). @@ -83,7 +83,7 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) { Create(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, create") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, create") }) } @@ -112,7 +112,7 @@ func TestDeleteRepositoryRbacAllowed(t *testing.T) { }, "org-admin") path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(path). Project("argo-project"). @@ -155,7 +155,7 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) { }, "org-admin") path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, true). + repoFixture.GivenWithSameState(t). When(). Path(path). Project("argo-project"). @@ -170,13 +170,13 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) { Delete(). Then(). AndCLIOutput(func(output string, err error) { - assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, delete") + assert.ErrorContains(t, err, "PermissionDenied desc = permission denied: repositories, delete") }) } func TestDeleteRepository(t *testing.T) { path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, false). + repoFixture.Given(t). When(). Path(path). Project("argo-project"). @@ -195,7 +195,7 @@ func TestDeleteRepository(t *testing.T) { func TestListRepoCLIOutput(t *testing.T) { path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, false). + repoFixture.Given(t). When(). Path(path). Project("argo-project"). @@ -215,7 +215,7 @@ git https://github.com/argoproj/argo-cd.git false false false fal func TestGetRepoCLIOutput(t *testing.T) { path := "https://github.com/argoproj/argo-cd.git" - repoFixture.Given(t, false). + repoFixture.Given(t). When(). Path(path). Project("argo-project"). diff --git a/test/e2e/selective_sync_test.go b/test/e2e/selective_sync_test.go index 491914be55184..2f7704aa6b2ea 100644 --- a/test/e2e/selective_sync_test.go +++ b/test/e2e/selective_sync_test.go @@ -111,6 +111,7 @@ func TestSelectiveSyncWithNamespace(t *testing.T) { } func getNewNamespace(t *testing.T) string { + t.Helper() randStr, err := rand.String(5) require.NoError(t, err) postFix := "-" + strings.ToLower(randStr) diff --git a/test/e2e/sync_options_test.go b/test/e2e/sync_options_test.go index b5dc685e76c13..fae78ed616328 100644 --- a/test/e2e/sync_options_test.go +++ b/test/e2e/sync_options_test.go @@ -53,11 +53,11 @@ func TestSyncWithStatusIgnored(t *testing.T) { Path(guestbookPath). When(). And(func() { - fixture.SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(fixture.SetResourceOverrides(map[string]ResourceOverride{ "/": { IgnoreDifferences: OverrideIgnoreDiff{JSONPointers: []string{"/status"}}, }, - }) + })) }). CreateFromFile(func(app *Application) { app.Spec.SyncPolicy = &SyncPolicy{Automated: &SyncPolicyAutomated{SelfHeal: true}} diff --git a/test/e2e/sync_waves_test.go b/test/e2e/sync_waves_test.go index 8d0ee14e487d1..8beda162e5708 100644 --- a/test/e2e/sync_waves_test.go +++ b/test/e2e/sync_waves_test.go @@ -6,6 +6,7 @@ import ( . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" @@ -20,11 +21,11 @@ func TestFixingDegradedApp(t *testing.T) { IgnoreErrors(). CreateApp(). And(func() { - SetResourceOverrides(map[string]ResourceOverride{ + errors.CheckError(SetResourceOverrides(map[string]ResourceOverride{ "ConfigMap": { HealthLua: `return { status = obj.metadata.annotations and obj.metadata.annotations['health'] or 'Degraded' }`, }, - }) + })) }). Sync(). Then(). diff --git a/test/e2e/sync_with_impersonate_test.go b/test/e2e/sync_with_impersonate_test.go index 7bb57af1156d3..4c7cf166f4a09 100644 --- a/test/e2e/sync_with_impersonate_test.go +++ b/test/e2e/sync_with_impersonate_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -16,32 +17,27 @@ import ( . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" ) -func TestSyncWithImpersonateDisable(t *testing.T) { - Given(t). - Path("guestbook"). - When(). - SetParamInSettingConfigMap("application.sync.impersonation.enabled", "false"). - CreateFromFile(func(app *v1alpha1.Application) { - app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} - }). - Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)) -} +const ( + WaitDuration = time.Second + TimeoutDuration = time.Second * 3 +) -func TestSyncWithImpersonateDefaultNamespaceServiceAccountNoRBAC(t *testing.T) { +func TestSyncWithFeatureDisabled(t *testing.T) { Given(t). Path("guestbook"). When(). - SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "false"). CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} }). Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) + // With the impersonation feature disabled, Application sync should continue to use + // the control plane service account for the sync operation and the sync should succeed. + ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeSynced), WaitDuration, TimeoutDuration). + Expect(OperationMessageContains("successfully synced")) } -func TestSyncWithImpersonateDefaultNamespaceServiceAccountWithRBAC(t *testing.T) { - roleName := "default-sa-role" +func TestSyncWithNoDestinationServiceAccountsInProject(t *testing.T) { Given(t). Path("guestbook"). When(). @@ -49,25 +45,11 @@ func TestSyncWithImpersonateDefaultNamespaceServiceAccountWithRBAC(t *testing.T) CreateFromFile(func(app *v1alpha1.Application) { app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} }). - And(func() { - err := createTestRole(roleName, fixture.DeploymentNamespace(), []rbac.PolicyRule{ - { - APIGroups: []string{"apps", ""}, - Resources: []string{"deployments"}, - Verbs: []string{"*"}, - }, - { - APIGroups: []string{""}, - Resources: []string{"services"}, - Verbs: []string{"*"}, - }, - }) - require.NoError(t, err) - err = createTestRoleBinding(roleName, "default", fixture.DeploymentNamespace()) - require.NoError(t, err) - }). Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) + // With the impersonation feature enabled, Application sync must fail + // when there are no destination service accounts configured in AppProject + ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync), WaitDuration, TimeoutDuration). + Expect(OperationMessageContains("failed to find a matching service account to impersonate")) } func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { @@ -89,7 +71,7 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { { Server: "*", Namespace: fixture.DeploymentNamespace(), - DefaultServiceAccount: "false-serviceAccount", + DefaultServiceAccount: "missing-serviceAccount", }, } err := createTestServiceAccount(serviceAccountName, fixture.DeploymentNamespace()) @@ -118,10 +100,13 @@ func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { app.Spec.Project = projectName }). Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)) + // With the impersonation feature enabled, Application sync should succeed + // as there is a valid match found in the available destination service accounts configured in AppProject + ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeSynced), WaitDuration, TimeoutDuration). + Expect(OperationMessageContains("successfully synced")) } -func TestSyncWithImpersonateWithFalseServiceAccount(t *testing.T) { +func TestSyncWithMissingServiceAccount(t *testing.T) { projectName := "false-test-project" serviceAccountName := "test-account" roleName := "test-account-sa-role" @@ -135,7 +120,7 @@ func TestSyncWithImpersonateWithFalseServiceAccount(t *testing.T) { { Server: "*", Namespace: fixture.DeploymentNamespace(), - DefaultServiceAccount: "false-serviceAccount", + DefaultServiceAccount: "missing-serviceAccount", }, { Server: "*", @@ -169,11 +154,15 @@ func TestSyncWithImpersonateWithFalseServiceAccount(t *testing.T) { app.Spec.Project = projectName }). Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) + // With the impersonation feature enabled, Application sync must fail + // when there is a valid match found in the available destination service accounts configured in AppProject, + // but the matching service account is missing. + ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync), WaitDuration, TimeoutDuration). + Expect(OperationMessageContains("one or more objects failed to apply")) } -func TestSyncWithNegationApplicationDestinationNamespace(t *testing.T) { - projectName := "nagation-test-project" +func TestSyncWithValidSAButDisallowedDestination(t *testing.T) { + projectName := "negation-test-project" serviceAccountName := "test-account" roleName := "test-account-sa-role" Given(t). @@ -217,6 +206,7 @@ func TestSyncWithNegationApplicationDestinationNamespace(t *testing.T) { Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)). When(). And(func() { + // Patch destination to disallow target destination namespace patch := []byte(fmt.Sprintf(`{"spec": {"destinations": [{"namespace": "%s"}]}}`, "!"+fixture.DeploymentNamespace())) _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Patch(context.Background(), projectName, types.MergePatchType, patch, metav1.PatchOptions{}) @@ -224,7 +214,10 @@ func TestSyncWithNegationApplicationDestinationNamespace(t *testing.T) { }). Refresh(v1alpha1.RefreshTypeNormal). Then(). - Expect(SyncStatusIs(v1alpha1.SyncStatusCodeUnknown)) + // With the impersonation feature enabled, Application sync must fail + // as there is a valid match found in the available destination service accounts configured in AppProject + // but the destination namespace is now disallowed. + ExpectConsistently(SyncStatusIs(v1alpha1.SyncStatusCodeUnknown), WaitDuration, TimeoutDuration) } // createTestAppProject creates a test AppProject resource. diff --git a/test/e2e/testdata/cmp-gitcreds/plugin.yaml b/test/e2e/testdata/cmp-gitcreds/plugin.yaml index 024804f495cc9..a256ce34de1f5 100644 --- a/test/e2e/testdata/cmp-gitcreds/plugin.yaml +++ b/test/e2e/testdata/cmp-gitcreds/plugin.yaml @@ -8,3 +8,4 @@ spec: command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GitAskpass\": \"$GIT_ASKPASS\"}}}"'] discover: fileName: "subdir/s*.yaml" + provideGitCreds: true diff --git a/test/e2e/testdata/cmp-gitcredstemplate/plugin.yaml b/test/e2e/testdata/cmp-gitcredstemplate/plugin.yaml index e57ee747bd078..18962b15b8b8d 100644 --- a/test/e2e/testdata/cmp-gitcredstemplate/plugin.yaml +++ b/test/e2e/testdata/cmp-gitcredstemplate/plugin.yaml @@ -8,3 +8,4 @@ spec: command: [sh, -c, 'echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GitAskpass\": \"$GIT_ASKPASS\", \"GitUsername\": \"$GIT_USERNAME\", \"GitPassword\": \"$GIT_PASSWORD\"}}}"'] discover: fileName: "subdir/s*.yaml" + provideGitCreds: true \ No newline at end of file diff --git a/test/e2e/testdata/cmp-gitsshcreds-disable-provide/generate.sh b/test/e2e/testdata/cmp-gitsshcreds-disable-provide/generate.sh new file mode 100644 index 0000000000000..0d6257f02478a --- /dev/null +++ b/test/e2e/testdata/cmp-gitsshcreds-disable-provide/generate.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +FILE=$(echo "$GIT_SSH_COMMAND" | grep -oP '\-i \K[/\w]+') +GIT_SSH_CRED_FILE_SHA=$(sha256sum ${FILE}) +echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GitSSHCommand\":\"$GIT_SSH_COMMAND\", \"GitSSHCredsFileSHA\":\"$GIT_SSH_CRED_FILE_SHA\"}}}" \ No newline at end of file diff --git a/test/e2e/testdata/cmp-gitsshcreds-disable-provide/plugin.yaml b/test/e2e/testdata/cmp-gitsshcreds-disable-provide/plugin.yaml new file mode 100644 index 0000000000000..5329037648535 --- /dev/null +++ b/test/e2e/testdata/cmp-gitsshcreds-disable-provide/plugin.yaml @@ -0,0 +1,11 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ConfigManagementPlugin +metadata: + name: cmp-gitsshcreds-disable-sharing +spec: + version: v1.0 + generate: + command: ["sh", "generate.sh"] + discover: + fileName: "subdir/s*.yaml" + provideGitCreds: false \ No newline at end of file diff --git a/test/e2e/testdata/cmp-gitsshcreds-disable-provide/subdir/special.yaml b/test/e2e/testdata/cmp-gitsshcreds-disable-provide/subdir/special.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/cmp-gitsshcreds/generate.sh b/test/e2e/testdata/cmp-gitsshcreds/generate.sh new file mode 100644 index 0000000000000..dfb5a285a0b84 --- /dev/null +++ b/test/e2e/testdata/cmp-gitsshcreds/generate.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +FILE=$(echo "$GIT_SSH_COMMAND" | grep -oP '\-i \K[/\w]+') +GIT_SSH_CRED_FILE_SHA=$(sha256sum ${FILE}) +echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"GitSSHCommand\":\"$GIT_SSH_COMMAND\", \"GitSSHCredsFileSHA\":\"$GIT_SSH_CRED_FILE_SHA\"}}}" \ No newline at end of file diff --git a/test/e2e/testdata/cmp-gitsshcreds/plugin.yaml b/test/e2e/testdata/cmp-gitsshcreds/plugin.yaml new file mode 100644 index 0000000000000..9d72603c5a40e --- /dev/null +++ b/test/e2e/testdata/cmp-gitsshcreds/plugin.yaml @@ -0,0 +1,11 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ConfigManagementPlugin +metadata: + name: cmp-gitsshcreds +spec: + version: v1.0 + generate: + command: ["sh", "generate.sh"] + discover: + fileName: "subdir/s*.yaml" + provideGitCreds: true \ No newline at end of file diff --git a/test/e2e/testdata/cmp-gitsshcreds/subdir/special.yaml b/test/e2e/testdata/cmp-gitsshcreds/subdir/special.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/empty-dir/.gitignore b/test/e2e/testdata/empty-dir/.gitignore new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/helm-repo/local/index.yaml b/test/e2e/testdata/helm-repo/local/index.yaml index 172cc0614966e..6e1a61435e61d 100644 --- a/test/e2e/testdata/helm-repo/local/index.yaml +++ b/test/e2e/testdata/helm-repo/local/index.yaml @@ -5,3 +5,4 @@ entries: urls: - http://127.0.0.1:9080/argo-e2e/testdata.git/helm-repo/helm-1.0.0.tgz version: 1.0.0 + name: helm diff --git a/test/e2e/testdata/helm-repo/local2/index.yaml b/test/e2e/testdata/helm-repo/local2/index.yaml index d41211cf0f660..711e1c5adf659 100644 --- a/test/e2e/testdata/helm-repo/local2/index.yaml +++ b/test/e2e/testdata/helm-repo/local2/index.yaml @@ -5,4 +5,5 @@ entries: urls: - http://127.0.0.1:9080/argo-e2e/testdata.git/helm-repo/helm-1.0.0.tgz version: 1.0.0 + name: helm diff --git a/test/e2e/testdata/helm-repo/remote/index.yaml b/test/e2e/testdata/helm-repo/remote/index.yaml index 2ce1fd789ff91..e43aec67572b0 100644 --- a/test/e2e/testdata/helm-repo/remote/index.yaml +++ b/test/e2e/testdata/helm-repo/remote/index.yaml @@ -5,3 +5,4 @@ entries: urls: - http://argocd-e2e-server:9080/helm-repo/helm-1.0.0.tgz version: 1.0.0 + name: helm \ No newline at end of file diff --git a/test/fixture/test/ci.go b/test/fixture/test/ci.go index 8a86a6d416dbf..44a98fc62093c 100644 --- a/test/fixture/test/ci.go +++ b/test/fixture/test/ci.go @@ -7,6 +7,7 @@ import ( // invoke this method to indicate test that should be skipped on CI, i.e. you only need it for manual testing/locally func LocalOnly(t *testing.T) { + t.Helper() if os.Getenv("CI") == "true" { t.Skipf("test %s skipped when envvar CI=true", t.Name()) } @@ -15,6 +16,7 @@ func LocalOnly(t *testing.T) { // invoke this method to indicate test should only run on CI, i.e. edge-case test on code that rarely changes and needs // extra software install func CIOnly(t *testing.T) { + t.Helper() if os.Getenv("CI") != "true" { t.Skipf("test %s skipped when envvar CI!=true", t.Name()) } diff --git a/test/fixture/test/flaky.go b/test/fixture/test/flaky.go index ae1c929f70bf7..79d222425a582 100644 --- a/test/fixture/test/flaky.go +++ b/test/fixture/test/flaky.go @@ -6,5 +6,6 @@ import ( // invoke this method to indicate it is a flaky test that should be skipped on CI func Flaky(t *testing.T) { + t.Helper() LocalOnly(t) } diff --git a/test/remote/Dockerfile b/test/remote/Dockerfile index fa649805767cc..062550e78000e 100644 --- a/test/remote/Dockerfile +++ b/test/remote/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 -FROM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS go +FROM docker.io/library/golang:1.23.4@sha256:81e1da9b9604cdee2bc226e90e15f9d51ae6a8cd2271dc341c42ca0926c3b83f AS go RUN go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest diff --git a/ui-test/.env b/ui-test/.env index 9e4c5b3d72259..4c2aa2475a363 100644 --- a/ui-test/.env +++ b/ui-test/.env @@ -21,6 +21,15 @@ IS_HEADLESS=true # URL of the ArgoCD UI to test against ARGOCD_URL=http://localhost:4000 # +# argocd app definition namespace +ARGOCD_NAMESPACE=argocd-e2e +# +# argocd credentials (if any) +#ARGOCD_AUTH_USERNAME=admin +# +# argocd credentials (if any) +#ARGOCD_AUTH_PASSWORD=password +# # Git repository where applications reside GIT_REPO=https://github.com/argoproj/argocd-example-apps # diff --git a/ui-test/Dockerfile b/ui-test/Dockerfile index c0fbd1be9b711..7469b94b002ea 100644 --- a/ui-test/Dockerfile +++ b/ui-test/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 as node +FROM docker.io/library/node:23.0.0@sha256:e643c0b70dca9704dff42e12b17f5b719dbe4f95e6392fc2dfa0c5f02ea8044d as node RUN apt-get update && apt-get install --no-install-recommends -y \ software-properties-common diff --git a/ui-test/package.json b/ui-test/package.json index a37fb07511461..73a695aff80a1 100644 --- a/ui-test/package.json +++ b/ui-test/package.json @@ -12,21 +12,21 @@ "author": "Keith Chong", "license": "Apache-2.0", "dependencies": { - "@types/selenium-webdriver": "^4.1.26", + "@types/selenium-webdriver": "^4.1.27", "assert": "^2.1.0", - "chromedriver": "^129.0.0", - "selenium-webdriver": "^4.24.1" + "chromedriver": "^131.0.3", + "selenium-webdriver": "^4.27.0" }, "devDependencies": { - "@types/mocha": "^10.0.8", - "@types/node": "^22.5.5", - "dotenv": "^16.4.5", + "@types/mocha": "^10.0.9", + "@types/node": "^22.9.3", + "dotenv": "^16.4.7", "mocha": "^10.7.3", "prettier": "^2.8.8", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.0.1", - "typescript": "^5.6.2", + "typescript": "^5.7.2", "yarn": "^1.22.22" } } diff --git a/ui-test/src/Configuration.ts b/ui-test/src/Configuration.ts index 33323433f1559..74fdd20f75096 100644 --- a/ui-test/src/Configuration.ts +++ b/ui-test/src/Configuration.ts @@ -1,4 +1,4 @@ -require('dotenv').config({path: __dirname + '/.env'}); +require('dotenv').config({path: __dirname + '/../.env'}); export default class Configuration { // Test specific @@ -6,6 +6,9 @@ export default class Configuration { public static readonly TEST_TIMEOUT: string | undefined = process.env.TEST_TIMEOUT; // ArgoCD UI specific. These are for single application-based tests, so one can quickly create an app based on the environment variables public static readonly ARGOCD_URL: string = process.env.ARGOCD_URL ? process.env.ARGOCD_URL : ''; + public static readonly ARGOCD_NAMESPACE: string = process.env.ARGOCD_NAMESPACE || 'argocd'; + public static readonly ARGOCD_AUTH_USERNAME: string = process.env.ARGOCD_AUTH_USERNAME || ''; + public static readonly ARGOCD_AUTH_PASSWORD: string = process.env.ARGOCD_AUTH_PASSWORD || ''; public static readonly APP_NAME: string = process.env.APP_NAME ? process.env.APP_NAME : ''; public static readonly APP_PROJECT: string = process.env.APP_PROJECT ? process.env.APP_PROJECT : ''; public static readonly GIT_REPO: string = process.env.GIT_REPO ? process.env.GIT_REPO : ''; diff --git a/ui-test/src/Constants.ts b/ui-test/src/Constants.ts index 89c1155774b22..f3f12dce52d4d 100644 --- a/ui-test/src/Constants.ts +++ b/ui-test/src/Constants.ts @@ -1,4 +1,4 @@ export const TEST_TIMEOUT: number = 60000; -export const TEST_SLIDING_PANEL_TIMEOUT: number = 6000; +export const TEST_SLIDING_PANEL_TIMEOUT: number = 10000; export const TEST_IS_NOT_VISIBLE_TIMEOUT: number = 5000; export const ENABLE_CONSOLE_LOG: boolean = true; diff --git a/ui-test/src/UiTestUtilities.ts b/ui-test/src/UiTestUtilities.ts index d66eaaed4cac7..ac38790ca1e4e 100644 --- a/ui-test/src/UiTestUtilities.ts +++ b/ui-test/src/UiTestUtilities.ts @@ -80,7 +80,7 @@ export default class UiTestUtilities { timeout = parseInt(Configuration.TEST_TIMEOUT, 10); } const element = await driver.wait(until.elementLocated(locator), timeout); - var isDisplayed = await element.isDisplayed(); + const isDisplayed = await element.isDisplayed(); if (isDisplayed) { await driver.wait(until.elementIsVisible(element), timeout); } diff --git a/ui-test/src/applications-list/applications-list.ts b/ui-test/src/applications-list/applications-list.ts index 3aa5e42ab2c8d..ae76b9d80c045 100644 --- a/ui-test/src/applications-list/applications-list.ts +++ b/ui-test/src/applications-list/applications-list.ts @@ -5,6 +5,7 @@ import {Base} from '../base'; import {ApplicationCreatePanel} from '../application-create-panel/application-create-panel'; import {ApplicationsSyncPanel, SYNC_PANEL_SYNCHRONIZE_BUTTON} from '../applications-sync-panel/applications-sync-panel'; import {PopupManager} from '../popup/popup-manager'; +import Configuration from '../Configuration'; const NEW_APP_BUTTON: By = By.xpath('.//button[@qe-id="applications-list-button-new-app"]'); // Uncomment to use: @@ -155,45 +156,39 @@ export class ApplicationsList extends Base { // Locators - // By.css('#app .applications-tiles .applications-list-" + appName + "''); + // By.css('#app .applications-tiles .applications-list-argocd_" + appName + "''); + + private getApplicationTileSelector(appName: string): string { + return './/div[contains(@class,"qe-applications-list-' + Configuration.ARGOCD_NAMESPACE + '_' + appName + '")]'; + } private getApplicationTileLocator(appName: string): By { - return By.xpath('.//div[contains(@class,"qe-applications-list-"' + appName + ')'); + return By.xpath(this.getApplicationTileSelector(appName)); } private getSyncButtonLocatorForApp(appName: string): By { - return By.xpath('.//div[contains(@class, "qe-applications-list-' + appName + '")]//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-sync"]'); + return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-sync"]'); } private getDeleteButtonLocatorForApp(appName: string): By { - return By.xpath('.//div[contains(@class, "qe-applications-list-' + appName + '")]//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-delete"]'); + return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-delete"]'); } private getRefreshButtonLocatorForApp(appName: string): By { - return By.xpath('.//div[contains(@class, "qe-applications-list-' + appName + '")]//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-refresh"]'); + return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//ancestor::a[@qe-id="applications-tiles-button-refresh"]'); } private getApplicationHealthTitle(appName: string): By { - return By.xpath( - './/div[contains(@class, "qe-applications-list-' + - appName + - '")]//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-health-status-title"]' - ); + return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-health-status-title"]'); } private getApplicationSyncTitle(appName: string): By { - return By.xpath( - './/div[contains(@class, "qe-applications-list-' + - appName + - '")]//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-sync-status-title"]' - ); + return By.xpath(this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-sync-status-title"]'); } private getApplicationOperationsTitle(appName: string): By { return By.xpath( - './/div[contains(@class, "qe-applications-list-' + - appName + - '")]//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-operations-status-title"]' + this.getApplicationTileSelector(appName) + '//div[@class="row"]//div[@qe-id="applications-tiles-health-status"]//i[@qe-id="utils-operations-status-title"]' ); } } diff --git a/ui-test/src/auth/login-page.ts b/ui-test/src/auth/login-page.ts new file mode 100644 index 0000000000000..29ff205cfa374 --- /dev/null +++ b/ui-test/src/auth/login-page.ts @@ -0,0 +1,28 @@ +import {By, WebDriver} from 'selenium-webdriver'; +import {Base} from '../base'; +import Configuration from '../Configuration'; +import UiTestUtilities from '../UiTestUtilities'; + +const LOGIN_FORM: By = By.css('#app .login__box form'); +const LOGIN_FORM_INPUT: By = By.css('input.argo-field'); +const LOGIN_FORM_BUTTON: By = By.css('button.argo-button'); + +export class AuthLoginPage extends Base { + public constructor(driver: WebDriver) { + super(driver); + } + + /** + * Fill login form and submit it + */ + public async loginWithCredentials() { + const loginForm = await UiTestUtilities.findUiElement(this.driver, LOGIN_FORM); + const inputs = await loginForm.findElements(LOGIN_FORM_INPUT); + const submitButton = await loginForm.findElement(LOGIN_FORM_BUTTON); + + await inputs[0].sendKeys(Configuration.ARGOCD_AUTH_USERNAME); + await inputs[1].sendKeys(Configuration.ARGOCD_AUTH_PASSWORD); + + await submitButton.click(); + } +} diff --git a/ui-test/src/navigation.ts b/ui-test/src/navigation.ts index 57588b86d464d..8baaff37e4d38 100644 --- a/ui-test/src/navigation.ts +++ b/ui-test/src/navigation.ts @@ -2,18 +2,25 @@ import {By, WebDriver} from 'selenium-webdriver'; import {ApplicationsList} from './applications-list/applications-list'; import UiTestUtilities from './UiTestUtilities'; import {Base} from './base'; +import {AuthLoginPage} from './auth/login-page'; -const NAVBAR_APPLICATIONS_BUTTON: By = By.css('#app .nav-bar .argo-icon-application'); -const NAVBAR_SETTINGS_BUTTON: By = By.css('#app .nav-bar .argo-icon-settings'); -const NAVBAR_USER_INFO_BUTTON: By = By.css('#app .nav-bar .fa-user-circle'); -const NAVBAR_DOCS_BUTTON: By = By.css('#app .nav-bar .argo-icon-docs'); +const NAVBAR_APPLICATIONS_BUTTON: By = By.css('#app .sidebar .argo-icon-application'); +const NAVBAR_SETTINGS_BUTTON: By = By.css('#app .sidebar .argo-icon-settings'); +const NAVBAR_USER_INFO_BUTTON: By = By.css('#app .sidebar .fa-user-circle'); +const NAVBAR_DOCS_BUTTON: By = By.css('#app .sidebar .argo-icon-docs'); export class Navigation extends Base { private applicationsList: ApplicationsList; + private authLoginPage: AuthLoginPage; public constructor(driver: WebDriver) { super(driver); this.applicationsList = new ApplicationsList(this.driver); + this.authLoginPage = new AuthLoginPage(this.driver); + } + + public getLoginPage(): AuthLoginPage { + return this.authLoginPage; } /** diff --git a/ui-test/src/test001.ts b/ui-test/src/test001.ts index 3db3f4d71413f..4c2fa604e3fc3 100644 --- a/ui-test/src/test001.ts +++ b/ui-test/src/test001.ts @@ -19,6 +19,10 @@ import {PopupManager} from './popup/popup-manager'; async function doTest() { const navigation = await UiTestUtilities.init(); try { + if (Configuration.ARGOCD_AUTH_USERNAME !== '') { + await navigation.getLoginPage().loginWithCredentials(); + } + const appsList: ApplicationsList = await navigation.clickApplicationsNavBarButton(); const applicationCreatePanel: ApplicationCreatePanel = await appsList.clickNewAppButton(); diff --git a/ui-test/src/test002.ts b/ui-test/src/test002.ts index 4e1f41fc05de0..f1c9e562250ca 100644 --- a/ui-test/src/test002.ts +++ b/ui-test/src/test002.ts @@ -2,6 +2,7 @@ import UiTestUtilities from './UiTestUtilities'; import {trace} from 'console'; import {ApplicationsList} from './applications-list/applications-list'; import {ApplicationCreatePanel} from './application-create-panel/application-create-panel'; +import Configuration from './Configuration'; /** * Test to demo how to visit each page via the navigation bar on the left. @@ -10,11 +11,17 @@ import {ApplicationCreatePanel} from './application-create-panel/application-cre async function doTest() { const navigation = await UiTestUtilities.init(); try { + if (Configuration.ARGOCD_AUTH_USERNAME !== '') { + await navigation.getLoginPage().loginWithCredentials(); + } + await navigation.clickDocsNavBarButton(); await navigation.clickUserInfoNavBarButton(); await navigation.clickSettingsNavBarButton(); const appsList: ApplicationsList = await navigation.clickApplicationsNavBarButton(); const applicationCreatePanel: ApplicationCreatePanel = await appsList.clickNewAppButton(); + // wait slide effect + await navigation.sleep(500); await applicationCreatePanel.clickCancelButton(); await UiTestUtilities.log('Test passed'); } catch (e) { diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index e937e6532293e..d8845dc5825aa 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -23,10 +23,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@bazel/runfiles@^5.8.1": - version "5.8.1" - resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-5.8.1.tgz#737d5b3dc9739767054820265cfe432a80564c82" - integrity sha512-NDdfpdQ6rZlylgv++iMn5FkObC/QlBQvipinGLSOguTYpRywmieOyJ29XHvUilspwTFSILWpoE9CqMGkHXug1g== +"@bazel/runfiles@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-6.3.1.tgz#3f8824b2d82853377799d42354b4df78ab0ace0b" + integrity sha512-1uLNT5NZsUVIGS4syuHwTzZ8HycMPyr6POA3FCE4GbMtc4rhoJk8aZKtNIRthJYfL+iioppi+rTfH3olMPr9nA== "@testim/chrome-version@^1.1.4": version "1.1.4" @@ -38,22 +38,22 @@ resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== -"@types/mocha@^10.0.8": - version "10.0.8" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.8.tgz#a7eff5816e070c3b4d803f1d3cd780c4e42934a1" - integrity sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw== +"@types/mocha@^10.0.9": + version "10.0.9" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.9.tgz#101e9da88d2c02e5ac8952982c23b224524d662a" + integrity sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q== -"@types/node@*", "@types/node@^22.5.5": - version "22.5.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" - integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== +"@types/node@*", "@types/node@^22.9.3": + version "22.9.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.3.tgz#08f3d64b3bc6d74b162d36f60213e8a6704ef2b4" + integrity sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" -"@types/selenium-webdriver@^4.1.26": - version "4.1.26" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.26.tgz#09c696a341cf8cfc1641cded11d14813350b6ca9" - integrity sha512-PUgqsyNffal0eAU0bzGlh37MJo558aporAPZoKqBeB/pF7zhKl1S3zqza0GpwFqgoigNxWhEIJzru75eeYco/w== +"@types/selenium-webdriver@^4.1.27": + version "4.1.27" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.27.tgz#e08000d649df6f099b4099432bd2fece9f50ea7b" + integrity sha512-ALqsj8D7Swb6MnBQuAQ58J3KC3yh6fLGtAmpBmnZX8j+0kmP7NaLt56CuzBw2W2bXPrvHFTgn8iekOQFUKXEQA== dependencies: "@types/node" "*" "@types/ws" "*" @@ -267,10 +267,10 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" -chromedriver@^129.0.0: - version "129.0.0" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-129.0.0.tgz#28d7ede5ab372b868ac0db5efff7036646b4d603" - integrity sha512-B1ccqD6hDjNrw94FeqdynIotn1ZV/TnFrkRz2Rync2kzSnq6D6IrSkN1w5Pnuvnc98QhN2xujxDXxkqEqy/PWg== +chromedriver@^131.0.3: + version "131.0.3" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-131.0.3.tgz#55f13389b855dbd681399aadd87a003bb0ab1186" + integrity sha512-DKHFt0ilcA/RJzY1ApBiJAil6fh08f9mXM8XbdDE1u+S1V5YVUNTUi4bOtJFZoAwS9nlV0H5W6InWrpXqSs2xg== dependencies: "@testim/chrome-version" "^1.1.4" axios "^1.7.4" @@ -418,10 +418,10 @@ diff@^5.2.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== -dotenv@^16.4.5: - version "16.4.5" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" - integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +dotenv@^16.4.7: + version "16.4.7" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" + integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== emoji-regex@^8.0.0: version "8.0.0" @@ -1272,12 +1272,12 @@ safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -selenium-webdriver@^4.24.1: - version "4.24.1" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.24.1.tgz#4315214420cc26dddaa21ae26863dd452aec2829" - integrity sha512-fcK5BTI/54cSqIhiVtrd9li1YL6LW109yIwuVw6V+FlVE6y4riGiX2qdZxVzHq+sm2TJyps+D2sjzXrpDZe1Og== +selenium-webdriver@^4.27.0: + version "4.27.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.27.0.tgz#f0f26ce453805e7dc77151040442c67e441dbe7a" + integrity sha512-LkTJrNz5socxpPnWPODQ2bQ65eYx9JK+DQMYNihpTjMCqHwgWGYQnQTCAAche2W3ZP87alA+1zYPvgS8tHNzMQ== dependencies: - "@bazel/runfiles" "^5.8.1" + "@bazel/runfiles" "^6.3.1" jszip "^3.10.1" tmp "^0.2.3" ws "^8.18.0" @@ -1483,12 +1483,12 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -typescript@^5.6.2: - version "5.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" - integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== +typescript@^5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== -undici-types@~6.19.2: +undici-types@~6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== diff --git a/ui/.nvmrc b/ui/.nvmrc index a8d3ff91fa10d..728f7de5c2da0 100644 --- a/ui/.nvmrc +++ b/ui/.nvmrc @@ -1 +1 @@ -v21.6.1 +22.9.0 diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index 7a9bfb21635bb..2d2e192590fa2 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -1,14 +1,15 @@ -import {DataLoader, NavigationManager, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui'; +import {DataLoader, NavigationManager, NotificationType, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui'; import {createBrowserHistory} from 'history'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import {Helmet} from 'react-helmet'; import {Redirect, Route, RouteComponentProps, Router, Switch} from 'react-router'; +import {Subscription} from 'rxjs'; import applications from './applications'; import help from './help'; import login from './login'; import settings from './settings'; -import {Layout} from './shared/components/layout/layout'; +import {Layout, ThemeWrapper} from './shared/components/layout/layout'; import {Page} from './shared/components/page/page'; import {VersionPanel} from './shared/components/version-info/version-info-panel'; import {AuthSettingsCtx, Provider} from './shared/context'; @@ -19,6 +20,7 @@ import {Banner} from './ui-banner/ui-banner'; import userInfo from './user-info'; import {AuthSettings} from './shared/models'; import {PKCEVerification} from './login/components/pkce-verify'; +import {getPKCERedirectURI, pkceLogin} from './login/components/utils'; import {SystemLevelExtension} from './shared/services/extensions-service'; services.viewPreferences.init(); @@ -86,28 +88,6 @@ async function isExpiredSSO() { return false; } -requests.onError.subscribe(async err => { - if (err.status === 401) { - if (history.location.pathname.startsWith('/login')) { - return; - } - - const isSSO = await isExpiredSSO(); - // location might change after async method call, so we need to check again. - if (history.location.pathname.startsWith('/login')) { - return; - } - // Query for basehref and remove trailing /. - // If basehref is the default `/` it will become an empty string. - const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, ''); - if (isSSO) { - window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`; - } else { - history.push(`/login?return_url=${encodeURIComponent(location.href)}`); - } - } -}); - export class App extends React.Component< {}, {popupProps: PopupProps; showVersionPanel: boolean; error: Error; navItems: NavItem[]; routes: Routes; extensionsLoaded: boolean; authSettings: AuthSettings} @@ -126,6 +106,8 @@ export class App extends React.Component< private navigationManager: NavigationManager; private navItems: NavItem[]; private routes: Routes; + private popupPropsSubscription: Subscription; + private unauthorizedSubscription: Subscription; constructor(props: {}) { super(props); @@ -135,11 +117,16 @@ export class App extends React.Component< this.navigationManager = new NavigationManager(history); this.navItems = navItems; this.routes = routes; + this.popupPropsSubscription = null; + this.unauthorizedSubscription = null; services.extensions.addEventListener('systemLevel', this.onAddSystemLevelExtension.bind(this)); } public async componentDidMount() { - this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps})); + this.popupPropsSubscription = this.popupManager.popupProps.subscribe(popupProps => this.setState({popupProps})); + this.subscribeUnauthorized().then(subscription => { + this.unauthorizedSubscription = subscription; + }); const authSettings = await services.authService.settings(); const {trackingID, anonymizeUsers} = authSettings.googleAnalytics || {trackingID: '', anonymizeUsers: true}; const {loggedIn, username} = await services.users.get(); @@ -167,6 +154,15 @@ export class App extends React.Component< this.setState({...this.state, navItems: this.navItems, routes: this.routes, extensionsLoaded: false, authSettings}); } + public componentWillUnmount() { + if (this.popupPropsSubscription) { + this.popupPropsSubscription.unsubscribe(); + } + if (this.unauthorizedSubscription) { + this.unauthorizedSubscription.unsubscribe(); + } + } + public render() { if (this.state.error != null) { const stack = this.state.error.stack; @@ -194,7 +190,7 @@ export class App extends React.Component< services.viewPreferences.getPreferences()}> - {pref =>
    {this.state.popupProps && }
    } + {pref => {this.state.popupProps && }}
    @@ -242,6 +238,41 @@ export class App extends React.Component< return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager}}; } + private async subscribeUnauthorized() { + return requests.onError.subscribe(async err => { + if (err.status === 401) { + if (history.location.pathname.startsWith('/login')) { + return; + } + + const isSSO = await isExpiredSSO(); + // location might change after async method call, so we need to check again. + if (history.location.pathname.startsWith('/login')) { + return; + } + // Query for basehref and remove trailing /. + // If basehref is the default `/` it will become an empty string. + const basehref = document.querySelector('head > base').getAttribute('href').replace(/\/$/, ''); + if (isSSO) { + const authSettings = await services.authService.settings(); + + if (authSettings?.oidcConfig?.enablePKCEAuthentication) { + pkceLogin(authSettings.oidcConfig, getPKCERedirectURI().toString()).catch(err => { + this.getChildContext().apis.notifications.show({ + type: NotificationType.Error, + content: err?.message || JSON.stringify(err) + }); + }); + } else { + window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`; + } + } else { + history.push(`/login?return_url=${encodeURIComponent(location.href)}`); + } + } + }); + } + private onAddSystemLevelExtension(extension: SystemLevelExtension) { const extendedNavItems = this.navItems; const extendedRoutes = this.routes; diff --git a/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap b/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap index f580fd6f66b35..81af34d623984 100644 --- a/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap +++ b/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap @@ -290,7 +290,7 @@ exports[`ResourceResultIcon.Hook.Terminating 1`] = ` exports[`ResourceResultIcon.Pruned 1`] = ` = { }, spec: { destination: { - name: '', + name: undefined, namespace: '', - server: '' + server: undefined }, source: { path: '', @@ -108,18 +108,18 @@ export const ApplicationCreatePanel = (props: { }) => { const [yamlMode, setYamlMode] = React.useState(false); const [explicitPathType, setExplicitPathType] = React.useState<{path: string; type: models.AppSourceType}>(null); - const [destFormat, setDestFormat] = React.useState('URL'); const [retry, setRetry] = React.useState(false); const app = deepMerge(DEFAULT_APP, props.app || {}); const debouncedOnAppChanged = debounce(props.onAppChanged, 800); + const [destinationFieldChanges, setDestinationFieldChanges] = React.useState({destFormat: 'URL', destFormatChanged: null}); + const comboSwitchedFromPanel = React.useRef(false); + let destinationComboValue = destinationFieldChanges.destFormat; React.useEffect(() => { - if (app?.spec?.destination?.name && app.spec.destination.name !== '') { - setDestFormat('NAME'); - } else { - setDestFormat('URL'); - } + comboSwitchedFromPanel.current = false; + }, []); + React.useEffect(() => { return () => { debouncedOnAppChanged.cancel(); }; @@ -135,6 +135,41 @@ export const ApplicationCreatePanel = (props: { formApi.setAllValues(appToNormalize); } + const currentName = app.spec.destination.name; + const currentServer = app.spec.destination.server; + if (destinationFieldChanges.destFormatChanged !== null) { + if (destinationComboValue == 'NAME') { + if (currentName === undefined && currentServer !== undefined && comboSwitchedFromPanel.current === false) { + destinationComboValue = 'URL'; + } else { + delete app.spec.destination.server; + if (currentName === undefined) { + app.spec.destination.name = ''; + } + } + } else { + if (currentServer === undefined && currentName !== undefined && comboSwitchedFromPanel.current === false) { + destinationComboValue = 'NAME'; + } else { + delete app.spec.destination.name; + if (currentServer === undefined) { + app.spec.destination.server = ''; + } + } + } + } else { + if (currentName === undefined && currentServer === undefined) { + destinationComboValue = destinationFieldChanges.destFormat; + app.spec.destination.server = ''; + } else { + if (currentName != undefined) { + destinationComboValue = 'NAME'; + } else { + destinationComboValue = 'URL'; + } + } + } + return (

    DESTINATION

    - {(destFormat.toUpperCase() === 'URL' && ( + {(destinationComboValue.toUpperCase() === 'URL' && (
    (

    - {destFormat} + {destinationComboValue}

    )} qeId='application-create-dropdown-destination' items={['URL', 'NAME'].map((type: 'URL' | 'NAME') => ({ title: type, action: () => { - if (destFormat !== type) { - const updatedApp = api.getFormState().values as models.Application; - if (type === 'URL') { - delete updatedApp.spec.destination.name; - } else { - delete updatedApp.spec.destination.server; - } - api.setAllValues(updatedApp); - setDestFormat(type); + if (destinationComboValue !== type) { + destinationComboValue = type; + comboSwitchedFromPanel.current = true; + setDestinationFieldChanges({destFormat: type, destFormatChanged: 'changed'}); } } }))} diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx index e98f46fc60e06..41fe11fe63ca8 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx @@ -1,9 +1,11 @@ import * as moment from 'moment'; import * as React from 'react'; +import * as classNames from 'classnames'; import * as models from '../../../shared/models'; import './application-deployment-history.scss'; +import '../../../shared/components/editable-panel/editable-panel.scss'; import {DataLoader} from 'argo-ui'; -import {Revision} from '../../../shared/components'; +import {Repo, Revision} from '../../../shared/components'; import {services} from '../../../shared/services'; import {ApplicationParameters} from '../application-parameters/application-parameters'; import {RevisionMetadataRows} from './revision-metadata-rows'; @@ -23,6 +25,63 @@ export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) = }); const [showParameterDetails, setShowParameterDetails] = React.useState(Boolean); + const [showSourceDetails, setShowSourceDetails] = React.useState([]); + const updateMap = (i: number) => { + if (i === null || i === undefined) { + return; + } + if (showSourceDetails.includes(i)) { + setShowSourceDetails(showSourceDetails.filter(item => item !== i)); + } else { + setShowSourceDetails([...showSourceDetails, i]); + } + }; + + const getCollapsedSection = (i: number, repoURL: string): React.ReactFragment => { + return ( +
    { + setShowParameterDetails(!showParameterDetails); + updateMap(i); + }}> +
    + +
    + +
    +
    {i != null ? 'Source ' + (i + 1) + ' Parameters' : 'Source Parameters'}
    +
    URL: {repoURL}
    +
    +
    + ); + }; + + const getExpandedSection = (index?: number): React.ReactFragment => { + return ( + +
    + { + setShowParameterDetails(!showParameterDetails); + updateMap(index); + }} + /> +
    +
    + ); + }; + + const getErrorSection = (err: React.ReactNode): React.ReactFragment => { + return ( +
    +

    {err}

    +
    + ); + }; return ( <> @@ -43,29 +102,32 @@ export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) = index={0} versionId={recentDeployments[index].id} /> - - {showParameterDetails && ( - services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    + {showParameterDetails ? ( +
    + {getExpandedSection()} + { + return getErrorSection(err); + }} + input={{...recentDeployments[index].source, targetRevision: recentDeployments[index].revision, appName: app.metadata.name}} + load={src => services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}> + {(details: models.RepoAppDetails) => ( +
    + +
    + )} +
    +
    + ) : ( + getCollapsedSection(null, recentDeployments[index].source.repoURL) )} ) : ( @@ -73,6 +135,12 @@ export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) = {i > 0 ?
    : null}
    +
    +
    Repo URL:
    +
    + +
    +
    Revision:
    @@ -87,35 +155,49 @@ export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) = index={i} versionId={recentDeployments[index].id} /> - - - {showParameterDetails && ( - services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    + {showSourceDetails.includes(i) ? ( +
    +
    + {getExpandedSection(i)} + { + return getErrorSection(err); + }} + input={{ + ...source, + targetRevision: recentDeployments[index].revisions[i], + index: i, + versionId: recentDeployments[index].id, + appName: app.metadata.name + }} + load={src => services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}> + {(details: models.RepoAppDetails) => ( + +
    +
    +
    Source {i + 1} Parameters
    +
    Repo URL: {source.repoURL}
    +
    {source.path ? 'Path: ' + source.path : ''}
    + + Revision: + +
    +
    + +
    + )} +
    +
    +
    + ) : ( + getCollapsedSection(i, source.repoURL) )} )) diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss index abacf037f48e5..3ec76c569d229 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss @@ -11,7 +11,6 @@ border-radius: $border-radius; box-shadow: 1px 1px 3px $argo-color-gray-5; margin-top: 1em; - overflow: hidden; & > .columns { padding: 1em; @@ -47,6 +46,18 @@ margin-left: -1em; } + .collapsible-section { + margin-top: 20px; + padding: 20px; + border: 1px solid; + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.1); + border-radius: '4px'; + @include themify($themes) { + border-color: themed('border'); + box-shadow: themed('shadow'); + } + } + .separator { height: 2px; margin: 1em 0; diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx index 69adefe598216..851d7d5c7bd14 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx @@ -20,7 +20,7 @@ export const ApplicationDeploymentHistory = ({ const recentDeployments = deployments.map((info, i) => { const nextDeployedAt = i === 0 ? null : deployments[i - 1].deployedAt; const runEnd = nextDeployedAt ? moment(nextDeployedAt) : moment(); - return {...info, nextDeployedAt, durationMs: runEnd.diff(moment(info.deployedAt)) / 1000}; + return {...info, nextDeployedAt, durationS: runEnd.diff(moment(info.deployedAt)) / 1000}; }); return ( @@ -37,7 +37,7 @@ export const ApplicationDeploymentHistory = ({
    Time to deploy:
    - {(info.deployStartedAt && ) || 'Unknown'} + {(info.deployStartedAt && ) || 'Unknown'}

    @@ -49,7 +49,7 @@ export const ApplicationDeploymentHistory = ({
    Active for:
    - +
    diff --git a/ui/src/app/applications/components/application-deployment-history/revision-metadata-rows.tsx b/ui/src/app/applications/components/application-deployment-history/revision-metadata-rows.tsx index 1043d0bfa5659..984bba4002128 100644 --- a/ui/src/app/applications/components/application-deployment-history/revision-metadata-rows.tsx +++ b/ui/src/app/applications/components/application-deployment-history/revision-metadata-rows.tsx @@ -4,8 +4,8 @@ import {Timestamp} from '../../../shared/components/timestamp'; import {ApplicationSource, RevisionMetadata, ChartDetails} from '../../../shared/models'; import {services} from '../../../shared/services'; -export const RevisionMetadataRows = (props: {applicationName: string; applicationNamespace: string; source: ApplicationSource; index: number; versionId: number}) => { - if (props.source.chart) { +export const RevisionMetadataRows = (props: {applicationName: string; applicationNamespace: string; source: ApplicationSource; index: number; versionId: number | null}) => { + if (props?.source?.chart) { return ( { const [opened, setOpened] = React.useState(false); @@ -42,7 +43,7 @@ export const ApplicationsDetailsAppDropdown = (props: {appName: string}) => { }) .slice(0, 100) // take top 100 results after filtering to avoid performance issues .map(app => ( -
  • ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`)}> +
  • ctx.navigation.goto(getAppUrl(app))}> {app.metadata.name} {app.metadata.name === props.appName && ' (current)'}
  • )) diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index c364e939054fb..3955f45d6f8fd 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -31,6 +31,7 @@ import {useSidebarTarget} from '../../../sidebar/sidebar'; import './application-details.scss'; import {TopBarActionMenuExt, AppViewExtension, StatusPanelExtension} from '../../../shared/services/extensions-service'; +import {ApplicationHydrateOperationState} from '../application-hydrate-operation-state/application-hydrate-operation-state'; interface ApplicationDetailsState { page: number; @@ -82,10 +83,46 @@ export class ApplicationDetails extends React.Component(null); - private appNamespace: string; constructor(props: RouteComponentProps<{appnamespace: string; name: string}>) { super(props); + this.state = { + page: 0, + groupedResources: [], + slidingPanelPage: 0, + filteredGraph: [], + truncateNameOnRight: false, + collapsedNodes: [], + ...this.getExtensionsState() + }; + } + + public componentDidMount() { + services.extensions.addEventListener('resource', this.onExtensionsUpdate); + services.extensions.addEventListener('appView', this.onExtensionsUpdate); + services.extensions.addEventListener('statusPanel', this.onExtensionsUpdate); + services.extensions.addEventListener('topBar', this.onExtensionsUpdate); + } + + public componentWillUnmount() { + services.extensions.removeEventListener('resource', this.onExtensionsUpdate); + services.extensions.removeEventListener('appView', this.onExtensionsUpdate); + services.extensions.removeEventListener('statusPanel', this.onExtensionsUpdate); + services.extensions.removeEventListener('topBar', this.onExtensionsUpdate); + } + + private getAppNamespace() { + if (typeof this.props.match.params.appnamespace === 'undefined') { + return ''; + } + return this.props.match.params.appnamespace; + } + + private onExtensionsUpdate = () => { + this.setState({...this.state, ...this.getExtensionsState()}); + }; + + private getExtensionsState = () => { const extensions = services.extensions.getAppViewExtensions(); const extensionsMap: {[key: string]: AppViewExtension} = {}; extensions.forEach(ext => { @@ -101,25 +138,11 @@ export class ApplicationDetails extends React.Component { topBarActionMenuExtsMap[ext.id] = ext; }); - this.state = { - page: 0, - groupedResources: [], - slidingPanelPage: 0, - filteredGraph: [], - truncateNameOnRight: false, - collapsedNodes: [], - extensions, - extensionsMap, - statusExtensions, - statusExtensionsMap, - topBarActionMenuExts, - topBarActionMenuExtsMap - }; - if (typeof this.props.match.params.appnamespace === 'undefined') { - this.appNamespace = ''; - } else { - this.appNamespace = this.props.match.params.appnamespace; - } + return {extensions, extensionsMap, statusExtensions, statusExtensionsMap, topBarActionMenuExts, topBarActionMenuExtsMap}; + }; + + private get showHydrateOperationState() { + return new URLSearchParams(this.props.history.location.search).get('hydrateOperation') === 'true'; } private get showOperationState() { @@ -296,7 +319,7 @@ export class ApplicationDetails extends React.Component Loading...} input={this.props.match.params.name} load={name => - combineLatest([this.loadAppInfo(name, this.props.match.params.appnamespace), services.viewPreferences.getPreferences(), q]).pipe( + combineLatest([this.loadAppInfo(name, this.getAppNamespace()), services.viewPreferences.getPreferences(), q]).pipe( map(items => { const application = items[0].application; const pref = items[1].appDetails; @@ -461,6 +484,7 @@ export class ApplicationDetails extends React.Component this.selectNode(appFullName, 0, 'diff')} showOperation={() => this.setOperationStatusVisible(true)} + showHydrateOperation={() => this.setHydrateOperationStatusVisible(true)} showConditions={() => this.setConditionsStatusVisible(true)} showExtension={id => this.setExtensionPanelVisible(id)} showMetadataInfo={revision => this.setState({...this.state, revision})} @@ -863,6 +888,11 @@ export class ApplicationDetails extends React.Component this.setOperationStatusVisible(false)}> {operationState && } + this.setHydrateOperationStatusVisible(false)}> + {hydrateOperationState && } + this.setConditionsStatusVisible(false)}> {conditions && } @@ -888,7 +918,7 @@ export class ApplicationDetails extends React.Component} this.setExtensionPanelVisible('')}> {this.selectedExtension !== '' && activeTopBarActionMenuExt?.flyout && ( @@ -919,19 +949,32 @@ export class ApplicationDetails extends React.Component, - action: () => this.selectNode(fullName) + action: () => this.selectNode(fullName), + disabled: !app.spec.source && (!app.spec.sources || app.spec.sources.length === 0) && !app.spec.sourceHydrator }, { iconClassName: 'fa fa-file-medical', title: , action: () => this.selectNode(fullName, 0, 'diff'), - disabled: app.status.sync.status === appModels.SyncStatuses.Synced + disabled: + app.status.sync.status === appModels.SyncStatuses.Synced || + (!app.spec.source && (!app.spec.sources || app.spec.sources.length === 0) && !app.spec.sourceHydrator) }, { iconClassName: 'fa fa-sync', title: , - action: () => AppUtils.showDeploy('all', null, this.appContext.apis) + action: () => AppUtils.showDeploy('all', null, this.appContext.apis), + disabled: !app.spec.source && (!app.spec.sources || app.spec.sources.length === 0) && !app.spec.sourceHydrator }, + ...(app.status?.operationState?.phase === 'Running' && app.status.resources.find(r => r.requiresDeletionConfirmation) + ? [ + { + iconClassName: 'fa fa-check', + title: , + action: () => this.confirmDeletion(app, 'Confirm Prunning', 'Are you sure you want to confirm resources pruning?') + } + ] + : []), { iconClassName: 'fa fa-info-circle', title: , @@ -946,11 +989,20 @@ export class ApplicationDetails extends React.Component, - action: () => this.deleteApplication() - }, + app.metadata.deletionTimestamp && + app.status.resources.find(r => r.requiresDeletionConfirmation) && + !((app.metadata.annotations || {})[appModels.AppDeletionConfirmedAnnotation] == 'true') + ? { + iconClassName: 'fa fa-check', + title: , + action: () => this.confirmDeletion(app, 'Confirm Deletion', 'Are you sure you want to delete this application?') + } + : { + iconClassName: 'fa fa-times-circle', + title: , + action: () => this.deleteApplication(), + disabled: !!app.metadata.deletionTimestamp + }, { iconClassName: classNames('fa fa-redo', {'status-icon--spin': !!refreshing}), title: ( @@ -1119,6 +1171,10 @@ export class ApplicationDetails extends React.Component { }; return ( - + {ResourceFilter({label: 'NAME', prefix: 'name', options: names.map(toOption), field: true})} {ResourceFilter({ label: 'KINDS', diff --git a/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.scss b/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.scss new file mode 100644 index 0000000000000..ca6959cf5d0a0 --- /dev/null +++ b/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.scss @@ -0,0 +1,18 @@ +.application-operation-state { + &__icons_container { + position: absolute; + left: 0; + } + + &__icons_container_padding { + left: 15px; + position: relative; + } + + &__message { + white-space: normal; + line-height: 16px; + display: inline-block; + vertical-align: middle; + } +} diff --git a/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.tsx b/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.tsx new file mode 100644 index 0000000000000..4c9171ad17dac --- /dev/null +++ b/ui/src/app/applications/components/application-hydrate-operation-state/application-hydrate-operation-state.tsx @@ -0,0 +1,76 @@ +import {Duration, Ticker} from 'argo-ui'; +import * as moment from 'moment'; +import * as PropTypes from 'prop-types'; +import * as React from 'react'; + +import {Revision, Timestamp} from '../../../shared/components'; +import * as models from '../../../shared/models'; + +import './application-hydrate-operation-state.scss'; + +interface Props { + hydrateOperationState: models.HydrateOperation; +} + +export const ApplicationHydrateOperationState: React.FunctionComponent = ({hydrateOperationState}) => { + const operationAttributes = [ + {title: 'PHASE', value: hydrateOperationState.phase}, + ...(hydrateOperationState.message ? [{title: 'MESSAGE', value: hydrateOperationState.message}] : []), + {title: 'STARTED AT', value: }, + { + title: 'DURATION', + value: ( + + {time => ( + + )} + + ) + } + ]; + + if (hydrateOperationState.finishedAt && hydrateOperationState.phase !== 'Hydrating') { + operationAttributes.push({title: 'FINISHED AT', value: }); + } + operationAttributes.push({ + title: 'DRY REVISION', + value: ( +
    + +
    + ) + }); + if (hydrateOperationState.finishedAt) { + operationAttributes.push({ + title: 'HYDRATED REVISION', + value: ( +
    + +
    + ) + }); + } + return ( +
    +
    +
    + {operationAttributes.map(attr => ( +
    +
    {attr.title}
    +
    {attr.value}
    +
    + ))} +
    +
    +
    + ); +}; + +ApplicationHydrateOperationState.contextTypes = { + apis: PropTypes.object +}; diff --git a/ui/src/app/applications/components/application-node-info/application-node-info.tsx b/ui/src/app/applications/components/application-node-info/application-node-info.tsx index 4d1f2720bf9a9..e98a56aaf14b0 100644 --- a/ui/src/app/applications/components/application-node-info/application-node-info.tsx +++ b/ui/src/app/applications/components/application-node-info/application-node-info.tsx @@ -12,6 +12,7 @@ import {ApplicationResourcesDiff} from '../application-resources-diff/applicatio import {ComparisonStatusIcon, formatCreationTimestamp, getPodReadinessGatesState, getPodStateReason, HealthStatusIcon} from '../utils'; import './application-node-info.scss'; import {ReadinessGatesNotPassedWarning} from './readiness-gates-not-passed-warning'; +import Moment from 'react-moment'; const RenderContainerState = (props: {container: any}) => { const state = (props.container.state?.waiting && 'waiting') || (props.container.state?.terminated && 'terminated') || (props.container.state?.running && 'running'); @@ -69,7 +70,13 @@ const RenderContainerState = (props: {container: any}) => { {lastState && ( <> <> - The container last terminated with exit code {lastState?.exitCode} + The container last terminated{' '} + + + {lastState.finishedAt} + {' '} + ago with exit code {lastState?.exitCode} + {lastState?.reason && ' because of '} @@ -233,11 +240,25 @@ export const ApplicationNodeInfo = (props: { } /> + + services.viewPreferences.updatePreferences({ + appDetails: { + ...pref.appDetails, + enableWordWrap: !pref.appDetails.enableWordWrap + } + }) + } + /> +
    services.applications.patchResource( props.application.metadata.name, @@ -280,7 +301,30 @@ export const ApplicationNodeInfo = (props: { tabs.push({ key: 'desiredManifest', title: 'Desired Manifest', - content: + content: ( + services.viewPreferences.getPreferences()}> + {pref => ( + +
    + + services.viewPreferences.updatePreferences({ + appDetails: { + ...pref.appDetails, + enableWordWrap: !pref.appDetails.enableWordWrap + } + }) + } + /> + +
    + +
    + )} +
    + ) }); } diff --git a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx index f6284258b238e..20c02bbfb04f9 100644 --- a/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx +++ b/ui/src/app/applications/components/application-operation-state/application-operation-state.tsx @@ -16,6 +16,7 @@ interface Props { operationState: models.OperationState; } const buildResourceUniqueId = (res: Omit) => `${res.group}-${res.kind}-${res.version}-${res.namespace}-${res.name}`; +const FilterableMessageStatuses = ['configured', 'unchanged']; const Filter = (props: {filters: string[]; setFilters: (f: string[]) => void; options: string[]; title: string; style?: React.CSSProperties}) => { const {filters, setFilters, options, title, style} = props; @@ -52,6 +53,8 @@ const Filter = (props: {filters: string[]; setFilters: (f: string[]) => void; op }; export const ApplicationOperationState: React.StatelessComponent = ({application, operationState}, ctx: AppContext) => { + const [messageFilters, setMessageFilters] = React.useState([]); + const operationAttributes = [ {title: 'OPERATION', value: utils.getOperationType(application)}, {title: 'PHASE', value: operationState.phase}, @@ -61,7 +64,9 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl title: 'DURATION', value: ( - {time => } + {time => ( + + )} ) } @@ -164,7 +169,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl if (combinedHealthSyncResult && combinedHealthSyncResult.length > 0) { filtered = combinedHealthSyncResult.filter(r => { - if (filters.length === 0 && healthFilters.length === 0) { + if (filters.length === 0 && healthFilters.length === 0 && messageFilters.length === 0) { return true; } @@ -177,6 +182,10 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl pass = false; } + if (pass && messageFilters.length !== 0) { + pass = messageFilters.some(filter => r.message?.toLowerCase().includes(filter.toLowerCase())); + } + return pass; }); } @@ -201,6 +210,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl +
    diff --git a/ui/src/app/applications/components/application-parameters/application-parameters.tsx b/ui/src/app/applications/components/application-parameters/application-parameters.tsx index ec6d67dae46a1..aacbfc6b20bfd 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -304,10 +304,10 @@ export const ApplicationParameters = (props: { props.handleCollapse(index, !currentState); }}>
    - +
    -
    Source {index + 1 + ': ' + appSource.repoURL}
    +
    Source {index + 1 + (appSource.name ? ' - ' + appSource.name : '') + ': ' + appSource.repoURL}
    {(appSource.path ? 'PATH=' + appSource.path : '') + (appSource.targetRevision ? (appSource.path ? ', ' : '') + 'REVISION=' + appSource.targetRevision : '')}
    @@ -320,7 +320,7 @@ export const ApplicationParameters = (props: {
    { props.handleCollapse(index, !props.collapsedSources[index]); }} @@ -586,6 +586,7 @@ function gatherCoreSourceDetails(i: number, attributes: EditablePanelItem[], sou const repoUrlField = 'spec.sources[' + i + '].repoURL'; const sourcesPathField = 'spec.sources[' + i + '].path'; const refField = 'spec.sources[' + i + '].ref'; + const nameField = 'spec.sources[' + i + '].name'; const chartField = 'spec.sources[' + i + '].chart'; const revisionField = 'spec.sources[' + i + '].targetRevision'; // For single source apps using the source field, these fields are shown in the Summary tab. @@ -595,6 +596,11 @@ function gatherCoreSourceDetails(i: number, attributes: EditablePanelItem[], sou view: , edit: (formApi: FormApi) => }); + attributes.push({ + title: 'NAME', + view: {source?.name}, + edit: (formApi: FormApi) => + }); if (isHelm) { attributes.push({ title: 'CHART', @@ -644,23 +650,24 @@ function gatherCoreSourceDetails(i: number, attributes: EditablePanelItem[], sou ) }); } else { + const targetRevision = source ? source.targetRevision || 'HEAD' : 'Unknown'; attributes.push({ title: 'TARGET REVISION', - view: , - edit: (formApi: FormApi) => + view: , + edit: (formApi: FormApi) => }); attributes.push({ title: 'PATH', view: ( - - {processPath(source.path)} + + {processPath(source?.path)} ), edit: (formApi: FormApi) => }); attributes.push({ title: 'REF', - view: {source.ref}, + view: {source?.ref}, edit: (formApi: FormApi) => }); } diff --git a/ui/src/app/applications/components/application-parameters/source-panel.tsx b/ui/src/app/applications/components/application-parameters/source-panel.tsx index 8e750b6e4a9b9..0e956670a6c08 100644 --- a/ui/src/app/applications/components/application-parameters/source-panel.tsx +++ b/ui/src/app/applications/components/application-parameters/source-panel.tsx @@ -57,6 +57,7 @@ const DEFAULT_APP: Partial = { path: '', repoURL: '', ref: '', + name: '', targetRevision: 'HEAD' }, sources: [], @@ -104,37 +105,37 @@ export const SourcePanel = (props: { } }); } - if (a.spec.source.repoURL && a.spec.source.chart) { + if (a.spec?.source?.repoURL && a.spec?.source?.chart) { props.appCurrent.spec.sources.forEach(source => { if ( - source.repoURL === a.spec.source.repoURL && - source.chart === a.spec.source.chart && - source.targetRevision === a.spec.source.targetRevision + source?.repoURL === a.spec?.source?.repoURL && + source?.chart === a.spec?.source?.chart && + source?.targetRevision === a.spec?.source?.targetRevision ) { sameChartVersion = true; chartError = 'Version ' + - source.targetRevision + + source?.targetRevision + ' of chart ' + - source.chart + + source?.chart + ' from the selected repository was already added to this multi-source application'; } }); } if (!samePath) { - if (!a.spec.source.path && !a.spec.source.chart && !a.spec.source.ref) { + if (!a.spec?.source?.path && !a.spec?.source?.chart && !a.spec?.source?.ref) { pathError = 'Path or Ref is required'; } } if (!sameChartVersion) { - if (!a.spec.source.chart && !a.spec.source.path && !a.spec.source.ref) { + if (!a.spec?.source?.chart && !a.spec?.source?.path && !a.spec?.source?.ref) { chartError = 'Chart is required'; } } return { - 'spec.source.repoURL': !a.spec.source.repoURL && 'Repository URL is required', + 'spec.source.repoURL': !a.spec?.source?.repoURL && 'Repository URL is required', // eslint-disable-next-line no-prototype-builtins - 'spec.source.targetRevision': !a.spec.source.targetRevision && a.spec.source.hasOwnProperty('chart') && 'Version is required', + 'spec.source.targetRevision': !a.spec?.source?.targetRevision && a.spec?.source?.hasOwnProperty('chart') && 'Version is required', 'spec.source.path': pathError, 'spec.source.chart': chartError }; @@ -157,8 +158,8 @@ export const SourcePanel = (props: { getApi={props.getFormApi}> {api => { // eslint-disable-next-line no-prototype-builtins - const repoType = (api.getFormState().values.spec.source.hasOwnProperty('chart') && 'helm') || 'git'; - const repoInfo = reposInfo.find(info => info.repo === api.getFormState().values.spec.source.repoURL); + const repoType = (api.getFormState().values.spec?.source?.hasOwnProperty('chart') && 'helm') || 'git'; + const repoInfo = reposInfo.find(info => info.repo === api.getFormState().values.spec?.source?.repoURL); if (repoInfo) { normalizeAppSource(appInEdit, repoInfo.type || 'git'); } @@ -204,14 +205,19 @@ export const SourcePanel = (props: {
    +
    +
    + +
    +
    {(repoType === 'git' && ( - +
    (src.repoURL && @@ -247,7 +253,7 @@ export const SourcePanel = (props: { new Array() }> {(charts: models.HelmChart[]) => { - const selectedChart = charts.find(chart => chart.name === api.getFormState().values.spec.source.chart); + const selectedChart = charts.find(chart => chart.name === api.getFormState().values.spec?.source?.chart); return (
    @@ -284,15 +290,15 @@ export const SourcePanel = (props: { const typePanel = () => ( { - if (src.repoURL && src.targetRevision && (src.path || src.chart)) { - return services.repos.appDetails(src, src.appName, props.appCurrent.spec.project, 0, 0).catch(() => ({ + if (src?.repoURL && src?.targetRevision && (src?.path || src?.chart)) { + return services.repos.appDetails(src, src?.appName, props.appCurrent.spec?.project, 0, 0).catch(() => ({ type: 'Directory', details: {} })); @@ -304,7 +310,7 @@ export const SourcePanel = (props: { } }}> {(details: models.RepoAppDetails) => { - const type = (explicitPathType && explicitPathType.path === appInEdit.spec.source.path && explicitPathType.type) || details.type; + const type = (explicitPathType && explicitPathType.path === appInEdit.spec?.source?.path && explicitPathType.type) || details.type; if (details.type !== type) { switch (type) { case 'Helm': @@ -337,7 +343,7 @@ export const SourcePanel = (props: { items={appTypes.map(item => ({ title: item.type, action: () => { - setExplicitPathType({type: item.type, path: appInEdit.spec.source.path}); + setExplicitPathType({type: item.type, path: appInEdit.spec?.source?.path}); normalizeTypeFields(api, item.type); } }))} diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx index 0e1cfb9a00783..c32e100927d82 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx @@ -291,7 +291,7 @@ function renderGroupedNodes(props: ApplicationResourceTreeProps, node: {count: n className='application-resource-tree__node-title application-resource-tree__direction-center-left' onClick={() => props.onGroupdNodeClick && props.onGroupdNodeClick(node.groupedNodeIds)} title={`Click to see details of ${node.count} collapsed ${node.kind} and doesn't contains any active pods`}> - {node.count} {node.kind}s + {node.count} {node.kind.endsWith('s') ? node.kind : `${node.kind}s`} {node.kind === 'ReplicaSet' ? ( }); const graphNodes = graph.nodes(); const size = getGraphSize(graphNodes.map(id => graph.node(id))); + + const resourceTreeRef = React.useRef(); + + const graphMoving = React.useRef({ + enable: false, + x: 0, + y: 0 + }); + + const onGraphDragStart: React.PointerEventHandler = e => { + if (e.target !== resourceTreeRef.current) { + return; + } + + if (!resourceTreeRef.current?.parentElement) { + return; + } + + graphMoving.current.enable = true; + graphMoving.current.x = e.clientX; + graphMoving.current.y = e.clientY; + }; + + const onGraphDragMoving: React.PointerEventHandler = e => { + if (!graphMoving.current.enable) { + return; + } + + if (!resourceTreeRef.current?.parentElement) { + return; + } + + const graphContainer = resourceTreeRef.current?.parentElement; + + const currentPositionX = graphContainer.scrollLeft; + const currentPositionY = graphContainer.scrollTop; + + const scrollLeft = currentPositionX + graphMoving.current.x - e.clientX; + const scrollTop = currentPositionY + graphMoving.current.y - e.clientY; + + graphContainer.scrollTo(scrollLeft, scrollTop); + + graphMoving.current.x = e.clientX; + graphMoving.current.y = e.clientY; + }; + + const onGraphDragEnd: React.PointerEventHandler = e => { + if (graphMoving.current.enable) { + graphMoving.current.enable = false; + e.preventDefault(); + } + }; return ( (graphNodes.length === 0 && ( @@ -1199,8 +1251,13 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) => )) || (
    + style={{width: size.width + 150, height: size.height + 250, transformOrigin: '0% 4%', transform: `scale(${props.zoom})`}}> {graphNodes.map(key => { const node = graph.node(key); const nodeType = node.type; diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss index e96c29624d5d1..5abceda464f31 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss @@ -181,6 +181,10 @@ } } + &__hydrator-link { + width: 134px; + } + &__item-name { margin: auto 0; max-width: $row-width; diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx index 643e24034d54a..43789bcd6b976 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx @@ -5,7 +5,15 @@ import {Revision} from '../../../shared/components/revision'; import {Timestamp} from '../../../shared/components/timestamp'; import * as models from '../../../shared/models'; import {services} from '../../../shared/services'; -import {ApplicationSyncWindowStatusIcon, ComparisonStatusIcon, getAppDefaultSource, getAppDefaultSyncRevisionExtra, getAppOperationState} from '../utils'; +import { + ApplicationSyncWindowStatusIcon, + ComparisonStatusIcon, + getAppDefaultSource, + getAppDefaultSyncRevisionExtra, + getAppOperationState, + HydrateOperationPhaseIcon, + hydrationStatusMessage +} from '../utils'; import {getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage, getAppDefaultSyncRevision, getAppDefaultOperationSyncRevision} from '../utils'; import {RevisionMetadataPanel} from './revision-metadata-panel'; import * as utils from '../utils'; @@ -16,6 +24,7 @@ interface Props { application: models.Application; showDiff?: () => any; showOperation?: () => any; + showHydrateOperation?: () => any; showConditions?: () => any; showExtension?: (id: string) => any; showMetadataInfo?: (revision: string) => any; @@ -46,7 +55,7 @@ const sectionHeader = (info: SectionInfo, onClick?: () => any) => { ); }; -export const ApplicationStatusPanel = ({application, showDiff, showOperation, showConditions, showExtension, showMetadataInfo}: Props) => { +export const ApplicationStatusPanel = ({application, showDiff, showOperation, showHydrateOperation, showConditions, showExtension, showMetadataInfo}: Props) => { const today = new Date(); let daysSinceLastSynchronized = 0; @@ -84,6 +93,40 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
    {application.status.health.message &&
    {application.status.health.message}
    }
    + {application.spec.sourceHydrator && application.status?.sourceHydrator?.currentOperation && ( +
    +
    + {sectionLabel({ + title: 'SOURCE HYDRATOR', + helpContent: 'The source hydrator reads manifests from git, hydrates (renders) them, and pushes them to a different location in git.' + })} +
    + +
    + {application.status.sourceHydrator.currentOperation.phase}{' '} + +
    + {application.status.sourceHydrator.currentOperation.message && ( +
    {application.status.sourceHydrator.currentOperation.message}
    + )} +
    + +
    +
    + )}
    {sectionHeader( @@ -112,12 +155,12 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh application.status.sync && (hasMultipleSources ? application.status.sync.revisions && application.status.sync.revisions[0] && application.spec.sources && !application.spec.sources[0].chart - : application.status.sync.revision && !application.spec.source.chart) && ( + : application.status.sync.revision && !application.spec?.source?.chart) && (
    @@ -160,7 +203,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh diff --git a/ui/src/app/applications/components/application-status-panel/revision-metadata-panel.tsx b/ui/src/app/applications/components/application-status-panel/revision-metadata-panel.tsx index 085958d0f1cf5..1816ae9e86552 100644 --- a/ui/src/app/applications/components/application-status-panel/revision-metadata-panel.tsx +++ b/ui/src/app/applications/components/application-status-panel/revision-metadata-panel.tsx @@ -8,7 +8,10 @@ export const RevisionMetadataPanel = (props: {appName: string; appNamespace: str return ; } return ( - services.applications.revisionMetadata(props.appName, props.appNamespace, props.revision, 0, props.versionId)} errorRenderer={() =>
    }> + services.applications.revisionMetadata(props.appName, props.appNamespace, props.revision, 0, props.versionId)} + errorRenderer={() =>
    }> {m => ( { }, !hasMultipleSources && { title: 'REPO URL', - view: , + view: , edit: (formApi: FormApi) => }, ...(!hasMultipleSources @@ -180,11 +180,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { ? [ { title: 'CHART', - view: ( - - {source.chart}:{source.targetRevision} - - ), + view: {source && `${source.chart}:${source.targetRevision}`}, edit: (formApi: FormApi) => hasMultipleSources ? ( helpTip('CHART is not editable for applications with multiple sources. You can edit them in the "Manifest" tab.') diff --git a/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx b/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx index 7cc24173cd36a..4e85bbbfefe5e 100644 --- a/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx +++ b/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx @@ -5,7 +5,7 @@ import * as ReactForm from 'react-form'; import './application-sync-options.scss'; -export const REPLACE_WARNING = `The resources will be synced using 'kubectl replace/create' command that is a potentially destructive action and might cause resources recreation.`; +export const REPLACE_WARNING = `The resources will be synced using 'kubectl replace/create' command that is a potentially destructive action and might cause resources recreation. For example, it might cause a number of pods to be reset to the minimum number of replicas and cause them to become overloaded.`; export const FORCE_WARNING = `The resources will be synced using '--force' that is a potentially destructive action and will immediately remove resources from the API and bypasses graceful deletion. Immediate deletion of some resources may result in inconsistency or data loss.`; export const PRUNE_ALL_WARNING = `The resources will be synced using '--prune', and all resources are marked to be pruned. Only continue if you want to delete all of the Application's resources.`; diff --git a/ui/src/app/applications/components/application-sync-panel/application-sync-panel.scss b/ui/src/app/applications/components/application-sync-panel/application-sync-panel.scss index a0e2eb7117e02..2cae5cd8c21f6 100644 --- a/ui/src/app/applications/components/application-sync-panel/application-sync-panel.scss +++ b/ui/src/app/applications/components/application-sync-panel/application-sync-panel.scss @@ -1,13 +1,28 @@ +@import 'node_modules/argo-ui/src/styles/config'; + .application-sync-panel__resource { margin-top: 0.5em; white-space: nowrap; + &:nth-of-type(odd) { + background: $argo-color-gray-3; + + .theme-dark & { + background: $argo-color-gray-6; + } + } + + &:nth-of-type(odd) { + background: #e0e0e0; + } + .container { - max-width: 32em; + max-width: 30em; white-space: nowrap; display: inline-block; margin-right: 0.3em; + label { cursor: pointer; } @@ -32,4 +47,4 @@ direction: rtl; // This is to help put the ellipsis in the middle instead of at the end of the resource path } } -} +} \ No newline at end of file diff --git a/ui/src/app/applications/components/applications-list/applications-filter.tsx b/ui/src/app/applications/components/applications-list/applications-filter.tsx index af1da7a371d0f..79534ee766d99 100644 --- a/ui/src/app/applications/components/applications-list/applications-filter.tsx +++ b/ui/src/app/applications/components/applications-list/applications-filter.tsx @@ -278,7 +278,7 @@ const AutoSyncFilter = (props: AppFilterProps) => ( export const ApplicationsFilter = (props: AppFilterProps) => { return ( - + diff --git a/ui/src/app/applications/components/applications-list/applications-list.tsx b/ui/src/app/applications/components/applications-list/applications-list.tsx index d6ddfeb343e66..764973e8106c4 100644 --- a/ui/src/app/applications/components/applications-list/applications-list.tsx +++ b/ui/src/app/applications/components/applications-list/applications-list.tsx @@ -390,6 +390,20 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => { {(applications: models.Application[]) => { const healthBarPrefs = pref.statusBarView || ({} as HealthStatusBarPreferences); const {filteredApps, filterResults} = filterApps(applications, pref, pref.search); + const handleCreatePanelClose = async () => { + const outsideDiv = document.querySelector('.sliding-panel__outside'); + const closeButton = document.querySelector('.sliding-panel__close'); + + if (outsideDiv && closeButton && closeButton !== document.activeElement) { + const confirmed = await ctx.popup.confirm('Close Panel', 'Closing this panel will discard all entered values. Continue?'); + if (confirmed) { + ctx.navigation.goto('.', {new: null}, {replace: true}); + } + } else if (closeButton === document.activeElement) { + // If the close button is focused or clicked, close without confirmation + ctx.navigation.goto('.', {new: null}, {replace: true}); + } + }; return ( ) => { ctx.navigation.goto('.', {new: null}, {replace: true})} + onClose={() => handleCreatePanelClose()} //Separate handling for outside click. header={
    - ( - - )}> - {() => AppUtils.renderResourceActionMenu(selectedNode, application, appContext)} - + {data.resourceActionsMenuItems?.length > 0 && ( + ( + + )}> + {() => AppUtils.renderResourceActionMenu(data.resourceActionsMenuItems)} + + )}
    { expect(tree).toMatchSnapshot(); }); + +// These tests are equivalent to those in controller/cache/info_test.go. If you change a test here, update the corresponding test there. +describe('getPodStateReason', () => { + it('TestGetPodInfo', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: helm-guestbook-pod + namespace: default + ownerReferences: + - apiVersion: extensions/v1beta1 + kind: ReplicaSet + name: helm-guestbook-rs + resourceVersion: "123" + labels: + app: guestbook + spec: + nodeName: minikube + containers: + - image: bar + resources: + requests: + memory: 128Mi + ` + + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Unknown'); + }); + + it('TestGetPodWithInitialContainerInfo', () => { + const podYaml = ` + apiVersion: "v1" + kind: "Pod" + metadata: + labels: + app: "app-with-initial-container" + name: "app-with-initial-container-5f46976fdb-vd6rv" + namespace: "default" + ownerReferences: + - apiVersion: "apps/v1" + kind: "ReplicaSet" + name: "app-with-initial-container-5f46976fdb" + spec: + containers: + - image: "alpine:latest" + imagePullPolicy: "Always" + name: "app-with-initial-container" + initContainers: + - image: "alpine:latest" + imagePullPolicy: "Always" + name: "app-with-initial-container-logshipper" + nodeName: "minikube" + status: + containerStatuses: + - image: "alpine:latest" + name: "app-with-initial-container" + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: "2024-10-08T08:44:25Z" + initContainerStatuses: + - image: "alpine:latest" + name: "app-with-initial-container-logshipper" + ready: true + restartCount: 0 + started: false + state: + terminated: + exitCode: 0 + reason: "Completed" + phase: "Running" +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Running'); + }); + + it('TestGetPodInfoWithSidecar', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + labels: + app: app-with-sidecar + name: app-with-sidecar-6664cc788c-lqlrp + namespace: default + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: app-with-sidecar-6664cc788c + spec: + containers: + - image: 'docker.m.daocloud.io/library/alpine:latest' + imagePullPolicy: Always + name: app-with-sidecar + initContainers: + - image: 'docker.m.daocloud.io/library/alpine:latest' + imagePullPolicy: Always + name: logshipper + restartPolicy: Always + nodeName: minikube + status: + containerStatuses: + - image: 'docker.m.daocloud.io/library/alpine:latest' + name: app-with-sidecar + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-08T08:39:43Z' + initContainerStatuses: + - image: 'docker.m.daocloud.io/library/alpine:latest' + name: logshipper + ready: true + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-08T08:39:40Z' + phase: Running +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Running'); + }); + + it('TestGetPodInfoWithInitialContainer', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + generateName: myapp-long-exist-56b7d8794d- + labels: + app: myapp-long-exist + name: myapp-long-exist-56b7d8794d-pbgrd + namespace: linghao + ownerReferences: + - apiVersion: apps/v1 + kind: ReplicaSet + name: myapp-long-exist-56b7d8794d + spec: + containers: + - image: alpine:latest + imagePullPolicy: Always + name: myapp-long-exist + initContainers: + - image: alpine:latest + imagePullPolicy: Always + name: myapp-long-exist-logshipper + nodeName: minikube + status: + containerStatuses: + - image: alpine:latest + name: myapp-long-exist + ready: false + restartCount: 0 + started: false + state: + waiting: + reason: PodInitializing + initContainerStatuses: + - image: alpine:latest + name: myapp-long-exist-logshipper + ready: false + restartCount: 0 + started: true + state: + running: + startedAt: '2024-10-09T08:03:45Z' + phase: Pending + startTime: '2024-10-09T08:02:39Z' +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Init:0/1'); + }); + + it('TestGetPodInfoWithRestartableInitContainer', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test1 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Pending + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: false + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + waiting: {} + started: false + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} + conditions: + - type: PodInitialized + status: "False" +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Init:0/2'); + }); + + it('TestGetPodInfoWithPartiallyStartedInitContainers', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test1 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Pending + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: true + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + running: {} + started: false + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} + conditions: + - type: PodInitialized + status: "False" +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Init:1/2'); + }); + + it('TestGetPodInfoWithStartedInitContainers', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test2 + spec: + initContainers: + - name: restartable-init-1 + restartPolicy: Always + - name: restartable-init-2 + restartPolicy: Always + containers: + - name: container + nodeName: minikube + status: + phase: Running + initContainerStatuses: + - name: restartable-init-1 + ready: false + restartCount: 3 + state: + running: {} + started: true + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + - name: restartable-init-2 + ready: false + state: + running: {} + started: true + containerStatuses: + - ready: true + restartCount: 4 + state: + running: {} + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with actual time + conditions: + - type: PodInitialized + status: "True" +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Running'); + }); + + it('TestGetPodInfoWithNormalInitContainer', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test7 + spec: + initContainers: + - name: init-container + containers: + - name: main-container + nodeName: minikube + status: + phase: podPhase + initContainerStatuses: + - ready: false + restartCount: 3 + state: + running: {} + lastTerminationState: + terminated: + finishedAt: "2023-10-01T00:00:00Z" # Replace with the actual time + containerStatuses: + - ready: false + restartCount: 0 + state: + waiting: {} +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + expect(reason).toBe('Init:0/1'); + }); + + it('TestPodConditionSucceeded', () => { + const podYaml = ` +apiVersion: v1 +kind: Pod +metadata: + name: test8 +spec: + nodeName: minikube + containers: + - name: container +status: + phase: Succeeded + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Completed + exitCode: 0 +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Completed'); + }); + + it('TestPodConditionFailed', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test9 + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Failed + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Error + exitCode: 1 +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Error'); + }); + + it('TestPodConditionSucceededWithDeletion', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test10 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Succeeded + containerStatuses: + - ready: false + restartCount: 0 + state: + terminated: + reason: Completed + exitCode: 0 +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Completed'); + }); + + it('TestPodConditionRunningWithDeletion', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test11 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Running + containerStatuses: + - ready: false + restartCount: 0 + state: + running: {} +`; + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Terminating'); + }); + + it('TestPodConditionPendingWithDeletion', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test12 + deletionTimestamp: "2023-10-01T00:00:00Z" + spec: + nodeName: minikube + containers: + - name: container + status: + phase: Pending + ` + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('Terminating'); + }); + + it('TestPodScheduledWithSchedulingGated', () => { + const podYaml = ` + apiVersion: v1 + kind: Pod + metadata: + name: test13 + spec: + nodeName: minikube + containers: + - name: container1 + - name: container2 + status: + phase: podPhase + conditions: + - type: PodScheduled + status: "False" + reason: SchedulingGated + ` + + const pod = jsYaml.load(podYaml); + + const {reason} = getPodStateReason(pod as State); + + expect(reason).toBe('SchedulingGated'); + }); +}); diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index 7e12416754afa..1e6511bc1bf1a 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -13,6 +13,7 @@ import {ResourceTreeNode} from './application-resource-tree/application-resource import {CheckboxField, COLORS, ErrorNotification, Revision} from '../../shared/components'; import * as appModels from '../../shared/models'; import {services} from '../../shared/services'; +import {ApplicationSource} from '../../shared/models'; require('./utils.scss'); @@ -223,6 +224,29 @@ export const OperationPhaseIcon = ({app}: {app: appModels.Application}) => { return ; }; +export const HydrateOperationPhaseIcon = ({operationState}: {operationState?: appModels.HydrateOperation}) => { + if (operationState === undefined) { + return ; + } + let className = ''; + let color = ''; + switch (operationState.phase) { + case appModels.HydrateOperationPhases.Hydrated: + className = 'fa fa-check-circle'; + color = COLORS.operation.success; + break; + case appModels.HydrateOperationPhases.Failed: + className = 'fa fa-times-circle'; + color = COLORS.operation.failed; + break; + default: + className = 'fa fa-circle-notch fa-spin'; + color = COLORS.operation.running; + break; + } + return ; +}; + export const ComparisonStatusIcon = ({ status, resource, @@ -496,7 +520,7 @@ export const deletePopup = async ( ); }; -function getResourceActionsMenuItems(resource: ResourceTreeNode, metadata: models.ObjectMeta, apis: ContextApis): Promise { +export function getResourceActionsMenuItems(resource: ResourceTreeNode, metadata: models.ObjectMeta, apis: ContextApis): Promise { return services.applications .getResourceActions(metadata.name, metadata.namespace, resource) .then(actions => { @@ -683,30 +707,24 @@ export function renderResourceMenu( ); } -export function renderResourceActionMenu(resource: ResourceTreeNode, application: appModels.Application, apis: ContextApis): React.ReactNode { - const menuItems = getResourceActionsMenuItems(resource, application.metadata, apis); - +export function renderResourceActionMenu(menuItems: ActionMenuItem[]): React.ReactNode { return ( - menuItems}> - {items => ( -
      - {items.map((item, i) => ( -
    • { - e.stopPropagation(); - if (!item.disabled) { - item.action(); - document.body.click(); - } - }}> - {item.iconClassName && } {item.title} -
    • - ))} -
    - )} -
    +
      + {menuItems.map((item, i) => ( +
    • { + e.stopPropagation(); + if (!item.disabled) { + item.action(); + document.body.click(); + } + }}> + {item.iconClassName && } {item.title} +
    • + ))} +
    ); } @@ -746,10 +764,10 @@ export function renderResourceButtons( export function syncStatusMessage(app: appModels.Application) { const source = getAppDefaultSource(app); const revision = getAppDefaultSyncRevision(app); - const rev = app.status.sync.revision || source.targetRevision || 'HEAD'; - let message = source.targetRevision || 'HEAD'; + const rev = app.status.sync.revision || (source ? source.targetRevision || 'HEAD' : 'Unknown'); + let message = source ? source?.targetRevision || 'HEAD' : 'Unknown'; - if (revision) { + if (revision && source) { if (source.chart) { message += ' (' + revision + ')'; } else if (revision.length >= 7 && !revision.startsWith(source.targetRevision)) { @@ -783,6 +801,65 @@ export function syncStatusMessage(app: appModels.Application) { } } +export function hydrationStatusMessage(app: appModels.Application) { + const drySource = app.status.sourceHydrator.currentOperation.sourceHydrator.drySource; + const dryCommit = app.status.sourceHydrator.currentOperation.drySHA; + const syncSource: ApplicationSource = { + repoURL: drySource.repoURL, + targetRevision: + app.status.sourceHydrator.currentOperation.sourceHydrator.hydrateTo?.targetBranch || app.status.sourceHydrator.currentOperation.sourceHydrator.syncSource.targetBranch, + path: app.status.sourceHydrator.currentOperation.sourceHydrator.syncSource.path + }; + const hydratedCommit = app.status.sourceHydrator.currentOperation.hydratedSHA || ''; + + switch (app.status.sourceHydrator.currentOperation.phase) { + case appModels.HydrateOperationPhases.Hydrated: + return ( + + from{' '} + + {drySource.targetRevision + ' (' + dryCommit.substr(0, 7) + ')'} + +
    + to{' '} + + {syncSource.targetRevision + ' (' + hydratedCommit.substr(0, 7) + ')'} + +
    + ); + case appModels.HydrateOperationPhases.Hydrating: + return ( + + from{' '} + + {drySource.targetRevision + ' (' + dryCommit.substr(0, 7) + ')'} + +
    + to{' '} + + {syncSource.targetRevision} + +
    + ); + case appModels.HydrateOperationPhases.Failed: + return ( + + from{' '} + + {drySource.targetRevision + ' (' + dryCommit.substr(0, 7) + ')'} + +
    + to{' '} + + {syncSource.targetRevision} + +
    + ); + default: + return {}; + } +} + export const HealthStatusIcon = ({state, noSpin}: {state: appModels.HealthStatus; noSpin?: boolean}) => { let color = COLORS.health.unknown; let icon = 'fa-question-circle'; @@ -874,7 +951,7 @@ export const ResourceResultIcon = ({resource}: {resource: appModels.ResourceResu break; case appModels.ResultCodes.Pruned: color = COLORS.sync_result.pruned; - icon = 'fa-heart'; + icon = 'fa-trash'; break; case appModels.ResultCodes.SyncFailed: color = COLORS.sync_result.failed; @@ -993,23 +1070,65 @@ export const OperationState = ({app, quiet}: {app: appModels.Application; quiet? ); }; +function isPodInitializedConditionTrue(status: any): boolean { + if (!status?.conditions) { + return false; + } + + for (const condition of status.conditions) { + if (condition.type !== 'Initialized') { + continue; + } + return condition.status === 'True'; + } + + return false; +} + +// isPodPhaseTerminal returns true if the pod's phase is terminal. +function isPodPhaseTerminal(phase: appModels.PodPhase): boolean { + return phase === appModels.PodPhase.PodFailed || phase === appModels.PodPhase.PodSucceeded; +} + export function getPodStateReason(pod: appModels.State): {message: string; reason: string; netContainerStatuses: any[]} { - let reason = pod.status.phase; + if (!pod.status) { + return {reason: 'Unknown', message: '', netContainerStatuses: []}; + } + + const podPhase = pod.status.phase; + let reason = podPhase; let message = ''; if (pod.status.reason) { reason = pod.status.reason; } - let initializing = false; - let netContainerStatuses = pod.status.initContainerStatuses || []; netContainerStatuses = netContainerStatuses.concat(pod.status.containerStatuses || []); - for (const container of (pod.status.initContainerStatuses || []).slice().reverse()) { + for (const condition of pod.status.conditions || []) { + if (condition.type === 'PodScheduled' && condition.reason === 'SchedulingGated') { + reason = 'SchedulingGated'; + } + } + + const initContainers: Record = {}; + + for (const container of pod.spec.initContainers ?? []) { + initContainers[container.name] = container; + } + + let initializing = false; + const initContainerStatuses = pod.status.initContainerStatuses || []; + for (let i = 0; i < initContainerStatuses.length; i++) { + const container = initContainerStatuses[i]; if (container.state.terminated && container.state.terminated.exitCode === 0) { continue; } + if (container.started && initContainers[container.name].restartPolicy === 'Always') { + continue; + } + if (container.state.terminated) { if (container.state.terminated.reason) { reason = `Init:ExitCode:${container.state.terminated.exitCode}`; @@ -1021,13 +1140,13 @@ export function getPodStateReason(pod: appModels.State): {message: string; reaso reason = `Init:${container.state.waiting.reason}`; message = `Init:${container.state.waiting.message}`; } else { - reason = `Init: ${(pod.spec.initContainers || []).length})`; + reason = `Init:${i}/${(pod.spec.initContainers || []).length}`; } initializing = true; break; } - if (!initializing) { + if (!initializing || isPodInitializedConditionTrue(pod.status)) { let hasRunning = false; for (const container of pod.status.containerStatuses || []) { if (container.state.waiting && container.state.waiting.reason) { @@ -1059,7 +1178,7 @@ export function getPodStateReason(pod: appModels.State): {message: string; reaso if ((pod as any).metadata.deletionTimestamp && pod.status.reason === 'NodeLost') { reason = 'Unknown'; message = ''; - } else if ((pod as any).metadata.deletionTimestamp) { + } else if ((pod as any).metadata.deletionTimestamp && !isPodPhaseTerminal(podPhase)) { reason = 'Terminating'; message = ''; } @@ -1084,7 +1203,7 @@ export const getPodReadinessGatesState = (pod: appModels.State): {nonExistingCon for (const condition of podStatusConditions) { existingConditions.set(condition.type, true); // priority order of conditions - // eg. if there are multiple conditions set with same name then the one which comes first is evaluated + // e.g. if there are multiple conditions set with same name then the one which comes first is evaluated if (podConditions.has(condition.type)) { continue; } @@ -1131,10 +1250,10 @@ export function isAppNode(node: appModels.ResourceNode) { export function getAppOverridesCount(app: appModels.Application) { const source = getAppDefaultSource(app); - if (source.kustomize && source.kustomize.images) { + if (source?.kustomize?.images) { return source.kustomize.images.length; } - if (source.helm && source.helm.parameters) { + if (source?.helm?.parameters) { return source.helm.parameters.length; } return 0; @@ -1146,7 +1265,7 @@ export function getAppDefaultSource(app?: appModels.Application) { if (!app) { return null; } - return app.spec.sources && app.spec.sources.length > 0 ? app.spec.sources[0] : app.spec.source; + return getAppSpecDefaultSource(app.spec); } // getAppDefaultSyncRevision gets the first app revisions from `status.sync.revisions` or, if that list is missing or empty, the `revision` @@ -1205,6 +1324,13 @@ export function getAppDefaultOperationSyncRevisionExtra(app?: appModels.Applicat } export function getAppSpecDefaultSource(spec: appModels.ApplicationSpec) { + if (spec.sourceHydrator) { + return { + repoURL: spec.sourceHydrator.drySource.repoURL, + targetRevision: spec.sourceHydrator.syncSource.targetBranch, + path: spec.sourceHydrator.syncSource.path + }; + } return spec.sources && spec.sources.length > 0 ? spec.sources[0] : spec.source; } @@ -1435,3 +1561,10 @@ export const userMsgsList: {[key: string]: string} = { groupNodes: `Since the number of pods has surpassed the threshold pod count of 15, you will now be switched to the group node view. If you prefer the tree view, you can simply click on the Group Nodes toolbar button to deselect the current view.` }; + +export function getAppUrl(app: appModels.Application): string { + if (typeof app.metadata.namespace === 'undefined') { + return `/applications/${app.metadata.name}`; + } + return `/applications/${app.metadata.namespace}/${app.metadata.name}`; +} diff --git a/ui/src/app/login/components/login.tsx b/ui/src/app/login/components/login.tsx index b00ef04bcacc4..0f1aa90f26052 100644 --- a/ui/src/app/login/components/login.tsx +++ b/ui/src/app/login/components/login.tsx @@ -65,14 +65,13 @@ export class Login extends React.Component, State> { { + onClick: () => pkceLogin(authSettings.oidcConfig, getPKCERedirectURI().toString()).catch(err => { this.appContext.apis.notifications.show({ type: NotificationType.Error, content: err?.message || JSON.stringify(err) }); - }); - } + }) } : {href: `auth/login?return_url=${encodeURIComponent(this.state.returnUrl)}`})}>
    ); diff --git a/ui/src/app/login/components/utils.ts b/ui/src/app/login/components/utils.ts index 94372797f4912..b363a4a934d63 100644 --- a/ui/src/app/login/components/utils.ts +++ b/ui/src/app/login/components/utils.ts @@ -13,6 +13,7 @@ import { validateAuthResponse } from 'oauth4webapi'; import {AuthSettings} from '../../shared/models'; +import requests from '../../shared/services/requests'; export const discoverAuthServer = (issuerURL: URL): Promise => discoveryRequest(issuerURL).then(res => processDiscoveryResponse(issuerURL, res)); @@ -31,7 +32,7 @@ export const PKCEState = { export const getPKCERedirectURI = () => { const currentOrigin = new URL(window.location.origin); - currentOrigin.pathname = '/pkce/verify'; + currentOrigin.pathname = requests.toAbsURL('/pkce/verify'); return currentOrigin; }; @@ -76,6 +77,12 @@ const validateAndGetOIDCForPKCE = async (oidcConfig: AuthSettings['oidcConfig']) export const pkceLogin = async (oidcConfig: AuthSettings['oidcConfig'], redirectURI: string) => { const {authorizationServer} = await validateAndGetOIDCForPKCE(oidcConfig); + // This sets the return path for the user after the pkce auth flow. + // This is ignored if the return path would be the login page as it would just loop. + if (!location.pathname.startsWith(requests.toAbsURL('/login'))) { + sessionStorage.setItem('return_url', location.pathname + location.search); + } + if (!authorizationServer.authorization_endpoint) { throw new PKCELoginError('No Authorization Server endpoint found'); } @@ -153,7 +160,18 @@ export const pkceCallback = async (queryParams: string, oidcConfig: AuthSettings throw new PKCELoginError('No token in response'); } - document.cookie = `argocd.token=${result.id_token}; path=/`; + // This regex removes any leading or trailing '/' characters and the result is appended to a '/'. + // This is because when base href if not just '/' toAbsURL() will append a trailing '/'. + // Just removing a trailing '/' from the string would break when base href is not specified, defaulted to '/'. + // This pattern is used to handle both cases. + document.cookie = `argocd.token=${result.id_token}; path=/${requests.toAbsURL('').replace(/^\/|\/$/g, '')}`; - window.location.replace('/applications'); + const returnURL = sessionStorage.getItem('return_url'); + + if (returnURL) { + sessionStorage.removeItem('return_url'); + window.location.replace(returnURL); + } else { + window.location.replace(requests.toAbsURL('/applications')); + } }; diff --git a/ui/src/app/settings/components/appearance-list/appearance-list.scss b/ui/src/app/settings/components/appearance-list/appearance-list.scss index dc70dcd77696c..44c8be678f60f 100644 --- a/ui/src/app/settings/components/appearance-list/appearance-list.scss +++ b/ui/src/app/settings/components/appearance-list/appearance-list.scss @@ -13,11 +13,13 @@ } border-radius: 4px; box-shadow: 1px 2px 3px rgba(#000, 0.1); - } + & .row { + justify-content: space-between; + align-items: center; - &__button { - position: absolute; - top: 25%; - right: 30px; + .select { + min-width: 160px; + } + } } -} \ No newline at end of file +} diff --git a/ui/src/app/settings/components/appearance-list/appearance-list.tsx b/ui/src/app/settings/components/appearance-list/appearance-list.tsx index 5e6fb06502f84..493f8bcf69ce7 100644 --- a/ui/src/app/settings/components/appearance-list/appearance-list.tsx +++ b/ui/src/app/settings/components/appearance-list/appearance-list.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import {DataLoader, Page} from '../../../shared/components'; import {services} from '../../../shared/services'; +import {Select, SelectOption} from 'argo-ui'; require('./appearance-list.scss'); @@ -16,16 +17,16 @@ export const AppearanceList = () => {
    -
    Dark Theme
    -
    - +
    + Dark Theme +
    diff --git a/ui/src/app/settings/components/cluster-details/cluster-details.tsx b/ui/src/app/settings/components/cluster-details/cluster-details.tsx index 472ccf26ee283..19ef81867dd4b 100644 --- a/ui/src/app/settings/components/cluster-details/cluster-details.tsx +++ b/ui/src/app/settings/components/cluster-details/cluster-details.tsx @@ -127,7 +127,9 @@ export const ClusterDetails = (props: RouteComponentProps<{server: string}>) => if (!cluster.info.connectionState.attemptedAt) { return Never (next refresh in few seconds); } - const secondsBeforeRefresh = Math.round(Math.max(10 - now.diff(moment(cluster.info.connectionState.attemptedAt)) / 1000, 1)); + const secondsBeforeRefresh = Math.round( + Math.max(10 - moment(now).diff(moment(cluster.info.connectionState.attemptedAt)) / 1000, 1) + ); return ( (next refresh in {secondsBeforeRefresh} seconds) diff --git a/ui/src/app/settings/components/project-details/project-details.tsx b/ui/src/app/settings/components/project-details/project-details.tsx index e77c501b70bbc..96110c2ff9cee 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -671,7 +671,7 @@ export class ProjectDetails extends React.Component {authCtx => - authCtx.appsInAnyNamespaceEnabled && ( + authCtx?.appsInAnyNamespaceEnabled && ( this.saveProject(item)} values={proj} diff --git a/ui/src/app/settings/components/repo-details/repo-details.tsx b/ui/src/app/settings/components/repo-details/repo-details.tsx index 017d87bede789..dc67d698350fd 100644 --- a/ui/src/app/settings/components/repo-details/repo-details.tsx +++ b/ui/src/app/settings/components/repo-details/repo-details.tsx @@ -4,9 +4,12 @@ import {FormApi, Text} from 'react-form'; import {EditablePanel, EditablePanelItem} from '../../../shared/components'; import * as models from '../../../shared/models'; import {NewHTTPSRepoParams} from '../repos-list/repos-list'; +import {AuthSettingsCtx} from '../../../shared/context'; export const RepoDetails = (props: {repo: models.Repository; save?: (params: NewHTTPSRepoParams) => Promise}) => { + const useAuthSettingsCtx = React.useContext(AuthSettingsCtx); const {repo, save} = props; + const write = false; const FormItems = (repository: models.Repository): EditablePanelItem[] => { const items: EditablePanelItem[] = [ { @@ -17,6 +20,11 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New title: 'Repository URL', view: repository.repo }, + { + title: 'Name', + view: repository.name || '', + edit: (formApi: FormApi) => + }, { title: 'Username (optional)', view: repository.username || '', @@ -29,11 +37,14 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New } ]; - if (repository.name) { - items.splice(1, 0, { - title: 'NAME', - view: repository.name - }); + if (useAuthSettingsCtx?.hydratorEnabled) { + // Insert this item at index 1. + const item = { + title: 'Write', + view: write, + edit: (formApi: FormApi) => + }; + items.splice(1, 0, item); } if (repository.project) { @@ -85,7 +96,8 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New password: !input.password && input.username && 'Password is required if username is given.' })} save={async input => { - const params: NewHTTPSRepoParams = {...newRepo}; + const params: NewHTTPSRepoParams = {...newRepo, write}; + params.name = input.name || ''; params.username = input.username || ''; params.password = input.password || ''; save(params); diff --git a/ui/src/app/settings/components/repos-list/repos-list.tsx b/ui/src/app/settings/components/repos-list/repos-list.tsx index 6b79ab490e359..92f7c63f53ba9 100644 --- a/ui/src/app/settings/components/repos-list/repos-list.tsx +++ b/ui/src/app/settings/components/repos-list/repos-list.tsx @@ -23,6 +23,8 @@ interface NewSSHRepoParams { proxy: string; noProxy: string; project?: string; + // write should be true if saving as a write credential. + write: boolean; } export interface NewHTTPSRepoParams { @@ -40,6 +42,8 @@ export interface NewHTTPSRepoParams { project?: string; forceHttpBasicAuth?: boolean; enableOCI: boolean; + // write should be true if saving as a write credential. + write: boolean; } interface NewGitHubAppRepoParams { @@ -57,6 +61,8 @@ interface NewGitHubAppRepoParams { proxy: string; noProxy: string; project?: string; + // write should be true if saving as a write credential. + write: boolean; } interface NewGoogleCloudSourceRepoParams { @@ -67,11 +73,15 @@ interface NewGoogleCloudSourceRepoParams { proxy: string; noProxy: string; project?: string; + // write should be true if saving as a write credential. + write: boolean; } interface NewSSHRepoCredsParams { url: string; sshPrivateKey: string; + // write should be true if saving as a write credential. + write: boolean; } interface NewHTTPSRepoCredsParams { @@ -84,6 +94,8 @@ interface NewHTTPSRepoCredsParams { noProxy: string; forceHttpBasicAuth: boolean; enableOCI: boolean; + // write should be true if saving as a write credential. + write: boolean; } interface NewGitHubAppRepoCredsParams { @@ -96,11 +108,15 @@ interface NewGitHubAppRepoCredsParams { tlsClientCertKey: string; proxy: string; noProxy: string; + // write should be true if saving as a write credential. + write: boolean; } interface NewGoogleCloudSourceRepoCredsParams { url: string; gcpServiceAccountKey: string; + // write should be true if saving as a write credential. + write: boolean; } export enum ConnectionMethod { @@ -117,6 +133,7 @@ export class ReposList extends React.Component< method: string; currentRepo: models.Repository; displayEditPanel: boolean; + authSettings: models.AuthSettings; } > { public static contextTypes = { @@ -136,10 +153,17 @@ export class ReposList extends React.Component< connecting: false, method: ConnectionMethod.SSH, currentRepo: null, - displayEditPanel: false + displayEditPanel: false, + authSettings: null }; } + public async componentDidMount() { + this.setState({ + authSettings: await services.authService.settings() + }); + } + private ConnectRepoFormButton(method: string, onSelection: (method: string) => void) { return (
    @@ -169,7 +193,7 @@ export class ReposList extends React.Component< } private onChooseDefaultValues = (): FormValues => { - return {type: 'git', ghType: 'GitHub'}; + return {type: 'git', ghType: 'GitHub', write: false}; }; private onValidateErrors(params: FormValues): FormErrors { @@ -346,7 +370,7 @@ export class ReposList extends React.Component< }, { title: 'Disconnect', - action: () => this.disconnectRepo(repo.repo, repo.project) + action: () => this.disconnectRepo(repo.repo, repo.project, false) } ]} /> @@ -389,7 +413,12 @@ export class ReposList extends React.Component< )} - items={[{title: 'Remove', action: () => this.removeRepoCreds(repo.url)}]} + items={[ + { + title: 'Remove', + action: () => this.removeRepoCreds(repo.url, false) + } + ]} />
    @@ -400,6 +429,129 @@ export class ReposList extends React.Component< }
    + {this.state.authSettings?.hydratorEnabled && ( +
    + services.repos.listWrite()} ref={loader => (this.repoLoader = loader)}> + {(repos: models.Repository[]) => + (repos.length > 0 && ( +
    +
    +
    +
    +
    TYPE
    +
    NAME
    +
    PROJECT
    +
    REPOSITORY
    +
    CONNECTION STATUS
    +
    +
    + {repos.map(repo => ( +
    (this.isRepoUpdatable(repo) ? this.displayEditSliding(repo) : null)}> +
    +
    + +
    +
    write
    +
    + + {repo.name} + +
    +
    + + {repo.project} + +
    +
    + + + + + +
    +
    + {repo.connectionState.status} + ( + + )} + items={[ + { + title: 'Create application', + action: () => + this.appContext.apis.navigation.goto('/applications', { + new: JSON.stringify({spec: {sourceHydrator: {drySource: {repoURL: repo.repo}}}}) + }) + }, + { + title: 'Disconnect', + action: () => this.disconnectRepo(repo.repo, repo.project, true) + } + ]} + /> +
    +
    +
    + ))} +
    + )) || ( + +

    No repositories connected

    +
    Connect your repo to deploy apps.
    +
    + ) + } + +
    + )} + {this.state.authSettings?.hydratorEnabled && ( +
    + services.repocreds.listWrite()} ref={loader => (this.credsLoader = loader)}> + {(creds: models.RepoCreds[]) => + creds.length > 0 && ( +
    +
    +
    +
    CREDENTIALS TEMPLATE URL
    +
    CREDS
    +
    +
    + {creds.map(repo => ( +
    +
    +
    + +
    +
    + - + ( + + )} + items={[ + { + title: 'Remove', + action: () => this.removeRepoCreds(repo.url, true) + } + ]} + /> +
    +
    +
    + ))} +
    + ) + } +
    +
    + )}
    this.onValidateErrors(values)}> {formApi => (
    - {this.state.method === ConnectionMethod.SSH && ( + {this.state.authSettings?.hydratorEnabled && (
    -

    CONNECT REPO USING SSH

    +

    SAVE AS WRITE CREDENTIAL (ALPHA)

    +

    + The Source Hydrator is an Alpha feature which enables Applications to push hydrated manifests to git before syncing. To use + the Source Hydrator for a repository, you must save two credentials: a read credential for pulling manifests and a write + credential for pushing hydrated manifests. If you add a write credential for a repository, then{' '} + any Application that can sync from the repo can also push hydrated manifests to that repo. Do not use this + feature until you've read its documentation and understand the security implications. +

    - -
    -
    - +
    +
    + )} + {this.state.method === ConnectionMethod.SSH && ( +
    +

    CONNECT REPO USING SSH

    + {formApi.getFormState().values.write === false && ( +
    + +
    + )} + {formApi.getFormState().values.write === false && ( +
    + +
    + )}
    @@ -452,10 +623,12 @@ export class ReposList extends React.Component<
    -
    - - -
    + {formApi.getFormState().values.write === false && ( +
    + + +
    + )}
    @@ -470,20 +643,27 @@ export class ReposList extends React.Component<
    - {formApi.getFormState().values.type === 'helm' && ( + {(formApi.getFormState().values.type === 'helm' || formApi.getFormState().values.type === 'git') && (
    - + +
    + )} + {formApi.getFormState().values.write === false && ( +
    +
    )} -
    - -
    @@ -701,11 +881,15 @@ export class ReposList extends React.Component< // Connect a new repository or create a repository credentials for SSH repositories private async connectSSHRepo(params: NewSSHRepoParams) { if (this.credsTemplate) { - this.createSSHCreds({url: params.url, sshPrivateKey: params.sshPrivateKey}); + this.createSSHCreds({url: params.url, sshPrivateKey: params.sshPrivateKey, write: params.write}); } else { this.setState({connecting: true}); try { - await services.repos.createSSH(params); + if (params.write) { + await services.repos.createSSHWrite(params); + } else { + await services.repos.createSSH(params); + } this.repoLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -731,12 +915,17 @@ export class ReposList extends React.Component< proxy: params.proxy, noProxy: params.noProxy, forceHttpBasicAuth: params.forceHttpBasicAuth, - enableOCI: params.enableOCI + enableOCI: params.enableOCI, + write: params.write }); } else { this.setState({connecting: true}); try { - await services.repos.createHTTPS(params); + if (params.write) { + await services.repos.createHTTPSWrite(params); + } else { + await services.repos.createHTTPS(params); + } this.repoLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -753,7 +942,11 @@ export class ReposList extends React.Component< // Update an existing repository for HTTPS repositories private async updateHTTPSRepo(params: NewHTTPSRepoParams) { try { - await services.repos.updateHTTPS(params); + if (params.write) { + await services.repos.updateHTTPSWrite(params); + } else { + await services.repos.updateHTTPS(params); + } this.repoLoader.reload(); this.setState({displayEditPanel: false}); this.refreshRepoList(params.url); @@ -779,12 +972,17 @@ export class ReposList extends React.Component< tlsClientCertData: params.tlsClientCertData, tlsClientCertKey: params.tlsClientCertKey, proxy: params.proxy, - noProxy: params.noProxy + noProxy: params.noProxy, + write: params.write }); } else { this.setState({connecting: true}); try { - await services.repos.createGitHubApp(params); + if (params.write) { + await services.repos.createGitHubAppWrite(params); + } else { + await services.repos.createGitHubApp(params); + } this.repoLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -803,12 +1001,17 @@ export class ReposList extends React.Component< if (this.credsTemplate) { this.createGoogleCloudSourceCreds({ url: params.url, - gcpServiceAccountKey: params.gcpServiceAccountKey + gcpServiceAccountKey: params.gcpServiceAccountKey, + write: params.write }); } else { this.setState({connecting: true}); try { - await services.repos.createGoogleCloudSource(params); + if (params.write) { + await services.repos.createGoogleCloudSourceWrite(params); + } else { + await services.repos.createGoogleCloudSource(params); + } this.repoLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -824,7 +1027,11 @@ export class ReposList extends React.Component< private async createHTTPSCreds(params: NewHTTPSRepoCredsParams) { try { - await services.repocreds.createHTTPS(params); + if (params.write) { + await services.repocreds.createHTTPSWrite(params); + } else { + await services.repocreds.createHTTPS(params); + } this.credsLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -837,7 +1044,11 @@ export class ReposList extends React.Component< private async createSSHCreds(params: NewSSHRepoCredsParams) { try { - await services.repocreds.createSSH(params); + if (params.write) { + await services.repocreds.createSSHWrite(params); + } else { + await services.repocreds.createSSH(params); + } this.credsLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -850,7 +1061,11 @@ export class ReposList extends React.Component< private async createGitHubAppCreds(params: NewGitHubAppRepoCredsParams) { try { - await services.repocreds.createGitHubApp(params); + if (params.write) { + await services.repocreds.createGitHubAppWrite(params); + } else { + await services.repocreds.createGitHubApp(params); + } this.credsLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -863,7 +1078,11 @@ export class ReposList extends React.Component< private async createGoogleCloudSourceCreds(params: NewGoogleCloudSourceRepoCredsParams) { try { - await services.repocreds.createGoogleCloudSource(params); + if (params.write) { + await services.repocreds.createGoogleCloudSourceWrite(params); + } else { + await services.repocreds.createGoogleCloudSource(params); + } this.credsLoader.reload(); this.showConnectRepo = false; } catch (e) { @@ -875,11 +1094,15 @@ export class ReposList extends React.Component< } // Remove a repository from the configuration - private async disconnectRepo(repo: string, project: string) { + private async disconnectRepo(repo: string, project: string, write: boolean) { const confirmed = await this.appContext.apis.popup.confirm('Disconnect repository', `Are you sure you want to disconnect '${repo}'?`); if (confirmed) { try { - await services.repos.delete(repo, project || ''); + if (write) { + await services.repos.deleteWrite(repo, project || ''); + } else { + await services.repos.delete(repo, project || ''); + } this.repoLoader.reload(); } catch (e) { this.appContext.apis.notifications.show({ @@ -891,11 +1114,15 @@ export class ReposList extends React.Component< } // Remove repository credentials from the configuration - private async removeRepoCreds(url: string) { + private async removeRepoCreds(url: string, write: boolean) { const confirmed = await this.appContext.apis.popup.confirm('Remove repository credentials', `Are you sure you want to remove credentials for URL prefix '${url}'?`); if (confirmed) { try { - await services.repocreds.delete(url); + if (write) { + await services.repocreds.deleteWrite(url); + } else { + await services.repocreds.delete(url); + } this.credsLoader.reload(); } catch (e) { this.appContext.apis.notifications.show({ diff --git a/ui/src/app/shared/components/editable-panel/editable-panel.scss b/ui/src/app/shared/components/editable-panel/editable-panel.scss index 7a4fee7d997a3..7ad9ae28014f9 100644 --- a/ui/src/app/shared/components/editable-panel/editable-panel.scss +++ b/ui/src/app/shared/components/editable-panel/editable-panel.scss @@ -1,4 +1,5 @@ @import 'node_modules/argo-ui/src/styles/config'; +@import 'node_modules/argo-ui/src/styles/theme'; .editable-panel { position: relative; @@ -32,6 +33,11 @@ position: absolute; top: 30px; right: 30px; + &__override { + @include themify($themes) { + color: themed('light-argo-teal-7'); + } + } } &__sticky-title { diff --git a/ui/src/app/shared/components/layout/layout.tsx b/ui/src/app/shared/components/layout/layout.tsx index e08297cb4e9e6..215120f9d8380 100644 --- a/ui/src/app/shared/components/layout/layout.tsx +++ b/ui/src/app/shared/components/layout/layout.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import {Sidebar} from '../../../sidebar/sidebar'; import {ViewPreferences} from '../../services'; +import {useTheme} from '../../utils'; require('./layout.scss'); @@ -13,15 +14,23 @@ export interface LayoutProps { const getBGColor = (theme: string): string => (theme === 'light' ? '#dee6eb' : '#100f0f'); +export const ThemeWrapper = (props: {children: React.ReactNode; theme: string}) => { + const [systemTheme] = useTheme({ + theme: props.theme + }); + return
    {props.children}
    ; +}; + export const Layout = (props: LayoutProps) => { + const [theme] = useTheme({theme: props.pref.theme}); React.useEffect(() => { - if (props.pref.theme) { - document.body.style.background = getBGColor(props.pref.theme); + if (theme) { + document.body.style.background = getBGColor(theme); } - }, [props.pref.theme]); + }, [theme]); return ( -
    +
    diff --git a/ui/src/app/shared/components/monaco-editor.tsx b/ui/src/app/shared/components/monaco-editor.tsx index a30381638f0b5..e0a34a06e9440 100644 --- a/ui/src/app/shared/components/monaco-editor.tsx +++ b/ui/src/app/shared/components/monaco-editor.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import * as monacoEditor from 'monaco-editor'; import {services} from '../services'; +import {getTheme, useSystemTheme} from '../utils'; export interface EditorInput { text: string; @@ -28,10 +29,25 @@ const MonacoEditorLazy = React.lazy(() => import('monaco-editor').then(monaco => { const Component = (props: MonacoProps) => { const [height, setHeight] = React.useState(0); + const [theme, setTheme] = React.useState('dark'); + + React.useEffect(() => { + const destroySystemThemeListener = useSystemTheme(systemTheme => { + if (theme === 'auto') { + monaco.editor.setTheme(systemTheme === 'dark' ? 'vs-dark' : 'vs'); + } + }); + + return () => { + destroySystemThemeListener(); + }; + }, [theme]); React.useEffect(() => { const subscription = services.viewPreferences.getPreferences().subscribe(preferences => { - monaco.editor.setTheme(preferences.theme === 'dark' ? 'vs-dark' : 'vs'); + setTheme(preferences.theme); + + monaco.editor.setTheme(getTheme(preferences.theme) === 'dark' ? 'vs-dark' : 'vs'); }); return () => { diff --git a/ui/src/app/shared/components/version-info/version-info-panel.tsx b/ui/src/app/shared/components/version-info/version-info-panel.tsx index 8622b762c8a5a..15edf463aae73 100644 --- a/ui/src/app/shared/components/version-info/version-info-panel.tsx +++ b/ui/src/app/shared/components/version-info/version-info-panel.tsx @@ -2,6 +2,7 @@ import {DataLoader, SlidingPanel, Tooltip} from 'argo-ui'; import * as React from 'react'; import {VersionMessage} from '../../models'; import {services} from '../../services'; +import {ThemeWrapper} from '../layout/layout'; interface VersionPanelProps { isShown: boolean; @@ -26,14 +27,14 @@ export class VersionPanel extends React.Component this.props.version}> {version => { return ( -
    + this.props.onClose()} hasCloseButton={true} isNarrow={true}>
    {this.buildVersionTable(version)}
    {this.getCopyButton(version)}
    -
    + ); }} diff --git a/ui/src/app/shared/components/yaml-editor/yaml-editor.tsx b/ui/src/app/shared/components/yaml-editor/yaml-editor.tsx index 5bcdbfdf17b39..824c3f9ffec8c 100644 --- a/ui/src/app/shared/components/yaml-editor/yaml-editor.tsx +++ b/ui/src/app/shared/components/yaml-editor/yaml-editor.tsx @@ -15,6 +15,7 @@ export class YamlEditor extends React.Component< hideModeButtons?: boolean; initialEditMode?: boolean; vScrollbar?: boolean; + enableWordWrap?: boolean; onSave?: (patch: string, patchType: string) => Promise; onCancel?: () => any; minHeight?: number; @@ -98,7 +99,11 @@ export class YamlEditor extends React.Component< vScrollBar={props.vScrollbar} editor={{ input: {text: yaml, language: 'yaml'}, - options: {readOnly: !this.state.editing, minimap: {enabled: false}}, + options: { + readOnly: !this.state.editing, + minimap: {enabled: false}, + wordWrap: props.enableWordWrap ? 'on' : 'off' + }, getApi: api => { this.model = api.getModel() as monacoEditor.editor.ITextModel; } diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index 9ee1df40452e4..eb65f370b011f 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -210,6 +210,29 @@ export interface ApplicationSource { directory?: ApplicationSourceDirectory; ref?: string; + + name?: string; +} + +export interface SourceHydrator { + drySource: DrySource; + syncSource: SyncSource; + hydrateTo?: HydrateTo; +} + +export interface DrySource { + repoURL: string; + targetRevision: string; + path: string; +} + +export interface SyncSource { + targetBranch: string; + path: string; +} + +export interface HydrateTo { + targetBranch: string; } export interface ApplicationSourceHelm { @@ -283,6 +306,7 @@ export interface ApplicationSpec { project: string; source: ApplicationSource; sources: ApplicationSource[]; + sourceHydrator?: SourceHydrator; destination: ApplicationDestination; syncPolicy?: SyncPolicy; ignoreDifferences?: ResourceIgnoreDifferences[]; @@ -354,6 +378,7 @@ export interface ResourceStatus { createdAt?: models.Time; hook?: boolean; requiresPruning?: boolean; + requiresDeletionConfirmation?: boolean; syncWave?: number; orphaned?: boolean; } @@ -442,8 +467,38 @@ export interface ApplicationStatus { health: HealthStatus; operationState?: OperationState; summary?: ApplicationSummary; + sourceHydrator?: SourceHydratorStatus; } +export interface SourceHydratorStatus { + lastSuccessfulOperation?: SuccessfulHydrateOperation; + currentOperation?: HydrateOperation; +} + +export interface HydrateOperation { + startedAt: models.Time; + finishedAt?: models.Time; + phase: HydrateOperationPhase; + message: string; + drySHA: string; + hydratedSHA: string; + sourceHydrator: SourceHydrator; +} + +export interface SuccessfulHydrateOperation { + drySHA: string; + hydratedSHA: string; + sourceHydrator: SourceHydrator; +} + +export type HydrateOperationPhase = 'Hydrating' | 'Failed' | 'Hydrated'; + +export const HydrateOperationPhases = { + Hydrating: 'Hydrating' as OperationPhase, + Failed: 'Failed' as OperationPhase, + Hydrated: 'Hydrated' as OperationPhase +}; + export interface JwtTokens { items: JwtToken[]; } @@ -501,6 +556,7 @@ export interface AuthSettings { uiBannerPosition: string; execEnabled: boolean; appsInAnyNamespaceEnabled: boolean; + hydratorEnabled: boolean; } export interface UserInfo { @@ -985,3 +1041,5 @@ export interface UserMessages { duration?: number; animation?: string; } + +export const AppDeletionConfirmedAnnotation = 'argocd.argoproj.io/deletion-approved'; diff --git a/ui/src/app/shared/services/applications-service.ts b/ui/src/app/shared/services/applications-service.ts index 1f7b5eb684416..3d812cad9512f 100644 --- a/ui/src/app/shared/services/applications-service.ts +++ b/ui/src/app/shared/services/applications-service.ts @@ -64,7 +64,7 @@ export class ApplicationsService { return r.then(res => res.body as models.RevisionMetadata); } - public revisionChartDetails(name: string, appNamespace: string, revision: string, sourceIndex: number, versionId: number): Promise { + public revisionChartDetails(name: string, appNamespace: string, revision: string, sourceIndex: number, versionId: number | null): Promise { let r = requests.get(`/applications/${name}/revisions/${revision || 'HEAD'}/chartdetails`).query({appNamespace}); if (sourceIndex !== null) { r = r.query({sourceIndex}); diff --git a/ui/src/app/shared/services/extensions-service.ts b/ui/src/app/shared/services/extensions-service.ts index 887b767df3305..20e5ca36f568b 100644 --- a/ui/src/app/shared/services/extensions-service.ts +++ b/ui/src/app/shared/services/extensions-service.ts @@ -3,7 +3,7 @@ import * as minimatch from 'minimatch'; import {Application, ApplicationTree, State} from '../models'; -type ExtensionsEventType = 'resource' | 'systemLevel' | 'appView' | 'statusPanel' | 'top-bar'; +type ExtensionsEventType = 'resource' | 'systemLevel' | 'appView' | 'statusPanel' | 'topBar'; type ExtensionsType = ResourceTabExtension | SystemLevelExtension | AppViewExtension | StatusPanelExtension | TopBarActionMenuExt; class ExtensionsEventTarget { @@ -73,7 +73,7 @@ function registerTopBarActionMenuExt( ) { const ext = {component, flyout, shouldDisplay, title, id, iconClassName, isMiddle}; extensions.topBarActionMenuExts.push(ext); - extensions.eventTarget.emit('top-bar', ext); + extensions.eventTarget.emit('topBar', ext); } let legacyInitialized = false; diff --git a/ui/src/app/shared/services/repo-service.ts b/ui/src/app/shared/services/repo-service.ts index 1b16bad02fcfb..f28a0d156d4a3 100644 --- a/ui/src/app/shared/services/repo-service.ts +++ b/ui/src/app/shared/services/repo-service.ts @@ -1,6 +1,62 @@ import * as models from '../models'; import requests from './requests'; +export interface HTTPSQuery { + type: string; + name: string; + url: string; + username: string; + password: string; + tlsClientCertData: string; + tlsClientCertKey: string; + insecure: boolean; + enableLfs: boolean; + proxy: string; + noProxy: string; + project?: string; + forceHttpBasicAuth?: boolean; + enableOCI: boolean; +} + +export interface SSHQuery { + type: string; + name: string; + url: string; + sshPrivateKey: string; + insecure: boolean; + enableLfs: boolean; + proxy: string; + noProxy: string; + project?: string; +} + +export interface GitHubAppQuery { + type: string; + name: string; + url: string; + githubAppPrivateKey: string; + githubAppId: bigint; + githubAppInstallationId: bigint; + githubAppEnterpriseBaseURL: string; + tlsClientCertData: string; + tlsClientCertKey: string; + insecure: boolean; + enableLfs: boolean; + proxy: string; + noProxy: string; + project?: string; +} + +export interface GoogleCloudSourceQuery { + type: string; + name: string; + url: string; + gcpServiceAccountKey: string; + proxy: string; + noProxy: string; + project?: string; +} + export class RepositoriesService { public list(): Promise { return requests @@ -9,6 +65,13 @@ export class RepositoriesService { .then(list => list.items || []); } + public listWrite(): Promise { + return requests + .get(`/write-repositories`) + .then(res => res.body as models.RepositoryList) + .then(list => list.items || []); + } + public listNoCache(): Promise { return requests .get(`/repositories?forceRefresh=true`) @@ -16,186 +79,205 @@ export class RepositoriesService { .then(list => list.items || []); } - public createHTTPS({ - type, - name, - url, - username, - password, - tlsClientCertData, - tlsClientCertKey, - insecure, - enableLfs, - proxy, - noProxy, - project, - forceHttpBasicAuth, - enableOCI - }: { - type: string; - name: string; - url: string; - username: string; - password: string; - tlsClientCertData: string; - tlsClientCertKey: string; - insecure: boolean; - enableLfs: boolean; - proxy: string; - noProxy: string; - project?: string; - forceHttpBasicAuth?: boolean; - enableOCI: boolean; - }): Promise { + public listWriteNoCache(): Promise { + return requests + .get(`/write-repositories?forceRefresh=true`) + .then(res => res.body as models.RepositoryList) + .then(list => list.items || []); + } + + public createHTTPS(q: HTTPSQuery): Promise { return requests .post('/repositories') - .send({type, name, repo: url, username, password, tlsClientCertData, tlsClientCertKey, insecure, enableLfs, proxy, noProxy, project, forceHttpBasicAuth, enableOCI}) + .send({ + type: q.type, + name: q.name, + repo: q.url, + username: q.username, + password: q.password, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project, + forceHttpBasicAuth: q.forceHttpBasicAuth, + enableOCI: q.enableOCI + }) + .then(res => res.body as models.Repository); + } + + public createHTTPSWrite(q: HTTPSQuery): Promise { + return requests + .post('/write-repositories') + .send({ + type: q.type, + name: q.name, + repo: q.url, + username: q.username, + password: q.password, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project, + forceHttpBasicAuth: q.forceHttpBasicAuth, + enableOCI: q.enableOCI + }) + .then(res => res.body as models.Repository); + } + + public updateHTTPS(q: HTTPSQuery): Promise { + return requests + .put(`/repositories/${encodeURIComponent(q.url)}`) + .send({ + type: q.type, + name: q.name, + repo: q.url, + username: q.username, + password: q.password, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project, + forceHttpBasicAuth: q.forceHttpBasicAuth, + enableOCI: q.enableOCI + }) .then(res => res.body as models.Repository); } - public updateHTTPS({ - type, - name, - url, - username, - password, - tlsClientCertData, - tlsClientCertKey, - insecure, - enableLfs, - proxy, - noProxy, - project, - forceHttpBasicAuth, - enableOCI - }: { - type: string; - name: string; - url: string; - username: string; - password: string; - tlsClientCertData: string; - tlsClientCertKey: string; - insecure: boolean; - enableLfs: boolean; - proxy: string; - noProxy: string; - project?: string; - forceHttpBasicAuth?: boolean; - enableOCI: boolean; - }): Promise { - return requests - .put(`/repositories/${encodeURIComponent(url)}`) - .send({type, name, repo: url, username, password, tlsClientCertData, tlsClientCertKey, insecure, enableLfs, proxy, noProxy, project, forceHttpBasicAuth, enableOCI}) + public updateHTTPSWrite(q: HTTPSQuery): Promise { + return requests + .put(`/write-repositories/${encodeURIComponent(q.url)}`) + .send({ + type: q.type, + name: q.name, + repo: q.url, + username: q.username, + password: q.password, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project, + forceHttpBasicAuth: q.forceHttpBasicAuth, + enableOCI: q.enableOCI + }) .then(res => res.body as models.Repository); } - public createSSH({ - type, - name, - url, - sshPrivateKey, - insecure, - enableLfs, - proxy, - noProxy, - project - }: { - type: string; - name: string; - url: string; - sshPrivateKey: string; - insecure: boolean; - enableLfs: boolean; - proxy: string; - noProxy: string; - project?: string; - }): Promise { + public createSSH(q: SSHQuery): Promise { return requests .post('/repositories') - .send({type, name, repo: url, sshPrivateKey, insecure, enableLfs, proxy, noProxy, project}) + .send({ + type: q.type, + name: q.name, + repo: q.url, + sshPrivateKey: q.sshPrivateKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project + }) .then(res => res.body as models.Repository); } - public createGitHubApp({ - type, - name, - url, - githubAppPrivateKey, - githubAppId, - githubAppInstallationId, - githubAppEnterpriseBaseURL, - tlsClientCertData, - tlsClientCertKey, - insecure, - enableLfs, - proxy, - noProxy, - project - }: { - type: string; - name: string; - url: string; - githubAppPrivateKey: string; - githubAppId: bigint; - githubAppInstallationId: bigint; - githubAppEnterpriseBaseURL: string; - tlsClientCertData: string; - tlsClientCertKey: string; - insecure: boolean; - enableLfs: boolean; - proxy: string; - noProxy: string; - project?: string; - }): Promise { + public createSSHWrite(q: SSHQuery): Promise { + return requests + .post('/write-repositories') + .send({ + type: q.type, + name: q.name, + repo: q.url, + sshPrivateKey: q.sshPrivateKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project + }) + .then(res => res.body as models.Repository); + } + + public createGitHubApp(q: GitHubAppQuery): Promise { return requests .post('/repositories') .send({ - type, - name, - repo: url, - githubAppPrivateKey, - githubAppId, - githubAppInstallationId, - githubAppEnterpriseBaseURL, - tlsClientCertData, - tlsClientCertKey, - insecure, - enableLfs, - proxy, - noProxy, - project + type: q.type, + name: q.name, + repo: q.url, + githubAppPrivateKey: q.githubAppPrivateKey, + githubAppId: q.githubAppId, + githubAppInstallationId: q.githubAppInstallationId, + githubAppEnterpriseBaseURL: q.githubAppEnterpriseBaseURL, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project + }) + .then(res => res.body as models.Repository); + } + + public createGitHubAppWrite(q: GitHubAppQuery): Promise { + return requests + .post('/write-repositories') + .send({ + type: q.type, + name: q.name, + repo: q.url, + githubAppPrivateKey: q.githubAppPrivateKey, + githubAppId: q.githubAppId, + githubAppInstallationId: q.githubAppInstallationId, + githubAppEnterpriseBaseURL: q.githubAppEnterpriseBaseURL, + tlsClientCertData: q.tlsClientCertData, + tlsClientCertKey: q.tlsClientCertKey, + insecure: q.insecure, + enableLfs: q.enableLfs, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project }) .then(res => res.body as models.Repository); } - public createGoogleCloudSource({ - type, - name, - url, - gcpServiceAccountKey, - proxy, - noProxy, - project - }: { - type: string; - name: string; - url: string; - gcpServiceAccountKey: string; - proxy: string; - noProxy: string; - project?: string; - }): Promise { + public createGoogleCloudSource(q: GoogleCloudSourceQuery): Promise { return requests .post('/repositories') .send({ - type, - name, - repo: url, - gcpServiceAccountKey, - proxy, - noProxy, - project + type: q.type, + name: q.name, + repo: q.url, + gcpServiceAccountKey: q.gcpServiceAccountKey, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project + }) + .then(res => res.body as models.Repository); + } + + public createGoogleCloudSourceWrite(q: GoogleCloudSourceQuery): Promise { + return requests + .post('/write-repositories') + .send({ + type: q.type, + name: q.name, + repo: q.url, + gcpServiceAccountKey: q.gcpServiceAccountKey, + proxy: q.proxy, + noProxy: q.noProxy, + project: q.project }) .then(res => res.body as models.Repository); } @@ -207,6 +289,13 @@ export class RepositoriesService { .then(res => res.body as models.Repository); } + public deleteWrite(url: string, project: string): Promise { + return requests + .delete(`/write-repositories/${encodeURIComponent(url)}?appProject=${project}`) + .send() + .then(res => res.body as models.Repository); + } + public async revisions(repo: string): Promise { return requests.get(`/repositories/${encodeURIComponent(repo)}/refs`).then(res => res.body as models.RefsInfo); } @@ -224,7 +313,7 @@ export class RepositoriesService { return requests.get(`/repositories/${encodeURIComponent(repo)}/helmcharts`).then(res => (res.body.items as models.HelmChart[]) || []); } - public appDetails(source: models.ApplicationSource, appName: string, appProject: string, sourceIndex: number, versionId: number): Promise { + public appDetails(source: models.ApplicationSource, appName: string, appProject: string, sourceIndex: number, versionId: number | null): Promise { return requests .post(`/repositories/${encodeURIComponent(source.repoURL)}/appdetails`) .send({source, appName, appProject, sourceIndex, versionId}) diff --git a/ui/src/app/shared/services/repocreds-service.ts b/ui/src/app/shared/services/repocreds-service.ts index b9f5f871eb12b..edac6d171d0fe 100644 --- a/ui/src/app/shared/services/repocreds-service.ts +++ b/ui/src/app/shared/services/repocreds-service.ts @@ -1,6 +1,38 @@ import * as models from '../models'; import requests from './requests'; +export interface HTTPSCreds { + url: string; + username: string; + password: string; + tlsClientCertData: string; + tlsClientCertKey: string; + proxy: string; + noProxy: string; +} + +export interface SSHCreds { + url: string; + sshPrivateKey: string; +} + +export interface GitHubAppCreds { + url: string; + githubAppPrivateKey: string; + githubAppId: bigint; + githubAppInstallationId: bigint; + githubAppEnterpriseBaseURL: string; + tlsClientCertData: string; + tlsClientCertKey: string; + proxy: string; + noProxy: string; +} + +export interface GoogleCloudSourceCreds { + url: string; + gcpServiceAccountKey: string; +} + export class RepoCredsService { public list(): Promise { return requests @@ -9,67 +41,66 @@ export class RepoCredsService { .then(list => list.items || []); } - public createHTTPS({ - url, - username, - password, - tlsClientCertData, - tlsClientCertKey, - proxy, - noProxy - }: { - url: string; - username: string; - password: string; - tlsClientCertData: string; - tlsClientCertKey: string; - proxy: string; - noProxy: string; - }): Promise { + public listWrite(): Promise { + return requests + .get('/write-repocreds') + .then(res => res.body as models.RepoCredsList) + .then(list => list.items || []); + } + + public createHTTPS(creds: HTTPSCreds): Promise { return requests .post('/repocreds') - .send({url, username, password, tlsClientCertData, tlsClientCertKey, proxy, noProxy}) + .send(creds) + .then(res => res.body as models.RepoCreds); + } + + public createHTTPSWrite(creds: HTTPSCreds): Promise { + return requests + .post('/write-repocreds') + .send(creds) .then(res => res.body as models.RepoCreds); } - public createSSH({url, sshPrivateKey}: {url: string; sshPrivateKey: string}): Promise { + public createSSH(creds: SSHCreds): Promise { return requests .post('/repocreds') - .send({url, sshPrivateKey}) + .send(creds) .then(res => res.body as models.RepoCreds); } - public createGitHubApp({ - url, - githubAppPrivateKey, - githubAppId, - githubAppInstallationId, - githubAppEnterpriseBaseURL, - tlsClientCertData, - tlsClientCertKey, - proxy, - noProxy - }: { - url: string; - githubAppPrivateKey: string; - githubAppId: bigint; - githubAppInstallationId: bigint; - githubAppEnterpriseBaseURL: string; - tlsClientCertData: string; - tlsClientCertKey: string; - proxy: string; - noProxy: string; - }): Promise { + public createSSHWrite(creds: SSHCreds): Promise { + return requests + .post('/write-repocreds') + .send(creds) + .then(res => res.body as models.RepoCreds); + } + + public createGitHubApp(creds: GitHubAppCreds): Promise { return requests .post('/repocreds') - .send({url, githubAppPrivateKey, githubAppId, githubAppInstallationId, githubAppEnterpriseBaseURL, tlsClientCertData, tlsClientCertKey, proxy, noProxy}) + .send(creds) .then(res => res.body as models.RepoCreds); } - public createGoogleCloudSource({url, gcpServiceAccountKey}: {url: string; gcpServiceAccountKey: string}): Promise { + public createGitHubAppWrite(creds: GitHubAppCreds): Promise { + return requests + .post('/write-repocreds') + .send(creds) + .then(res => res.body as models.RepoCreds); + } + + public createGoogleCloudSource(creds: GoogleCloudSourceCreds): Promise { return requests .post('/repocreds') - .send({url, gcpServiceAccountKey}) + .send(creds) + .then(res => res.body as models.RepoCreds); + } + + public createGoogleCloudSourceWrite(creds: GoogleCloudSourceCreds): Promise { + return requests + .post('/write-repocreds') + .send(creds) .then(res => res.body as models.RepoCreds); } @@ -79,4 +110,11 @@ export class RepoCredsService { .send() .then(res => res.body as models.RepoCreds); } + + public deleteWrite(url: string): Promise { + return requests + .delete(`/write-repocreds/${encodeURIComponent(url)}`) + .send() + .then(res => res.body as models.RepoCreds); + } } diff --git a/ui/src/app/shared/services/view-preferences-service.ts b/ui/src/app/shared/services/view-preferences-service.ts index b6cdbbdc08a46..575c4b734d416 100644 --- a/ui/src/app/shared/services/view-preferences-service.ts +++ b/ui/src/app/shared/services/view-preferences-service.ts @@ -20,6 +20,7 @@ export interface AppDetailsPreferences { inlineDiff: boolean; compactDiff: boolean; hideManagedFields?: boolean; + enableWordWrap?: boolean; orphanedResources: boolean; podView: PodViewPreferences; darkMode: boolean; diff --git a/ui/src/app/shared/utils.ts b/ui/src/app/shared/utils.ts index c57715a8f933d..129b8e769a951 100644 --- a/ui/src/app/shared/utils.ts +++ b/ui/src/app/shared/utils.ts @@ -1,3 +1,5 @@ +import React from 'react'; + export function hashCode(str: string) { let hash = 0; for (let i = 0; i < str.length; i++) { @@ -34,3 +36,71 @@ export function isValidURL(url: string): boolean { } } } + +export const colorSchemes = { + light: '(prefers-color-scheme: light)', + dark: '(prefers-color-scheme: dark)' +}; + +/** + * quick method to check system theme + * @param theme auto, light, dark + * @returns dark or light + */ +export function getTheme(theme: string) { + if (theme !== 'auto') { + return theme; + } + + const dark = window.matchMedia(colorSchemes.dark); + + return dark.matches ? 'dark' : 'light'; +} + +/** + * create a listener for system theme + * @param cb callback for theme change + * @returns destroy listener + */ +export const useSystemTheme = (cb: (theme: string) => void) => { + const dark = window.matchMedia(colorSchemes.dark); + const light = window.matchMedia(colorSchemes.light); + + const listener = () => { + cb(dark.matches ? 'dark' : 'light'); + }; + + dark.addEventListener('change', listener); + light.addEventListener('change', listener); + + return () => { + dark.removeEventListener('change', listener); + light.removeEventListener('change', listener); + }; +}; + +export const useTheme = (props: {theme: string}) => { + const [theme, setTheme] = React.useState(getTheme(props.theme)); + + React.useEffect(() => { + let destroyListener: (() => void) | undefined; + + // change theme by system, only register listener when theme is auto + if (props.theme === 'auto') { + destroyListener = useSystemTheme(systemTheme => { + setTheme(systemTheme); + }); + } + + // change theme manually + if (props.theme !== theme) { + setTheme(getTheme(props.theme)); + } + + return () => { + destroyListener?.(); + }; + }, [props.theme]); + + return [theme]; +}; diff --git a/ui/yarn.lock b/ui/yarn.lock index fb1668982538a..dc29f24753a2f 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2872,7 +2872,7 @@ arg@^4.1.0: "argo-ui@git+https://github.com/argoproj/argo-ui.git": version "1.0.0" - resolved "git+https://github.com/argoproj/argo-ui.git#4836620cfc729d7c732b9b562fc4c03051e9598a" + resolved "git+https://github.com/argoproj/argo-ui.git#d9a4285dc254bc473b9f26f5d72655296233f003" dependencies: "@fortawesome/fontawesome-free" "^6.2.1" "@tippy.js/react" "^3.1.1" @@ -2881,7 +2881,6 @@ arg@^4.1.0: core-js "^3.32.1" foundation-sites "^6.4.3" history "^4.10.1" - moment "^2.29.4" prop-types "^15.8.1" react-autocomplete "1.8.1" react-form "^2.16.0" @@ -5639,9 +5638,9 @@ http-proxy-agent@^5.0.0: debug "4" http-proxy-middleware@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a" - integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg== + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -6121,7 +6120,7 @@ is-wsl@^2.2.0: isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== isarray@^2.0.5: version "2.0.5" @@ -7186,9 +7185,9 @@ multicast-dns@^6.0.1: thunky "^1.0.2" nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== natural-compare@^1.4.0: version "1.4.0" @@ -7642,9 +7641,9 @@ path-to-regexp@0.1.10: integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.9.0.tgz#5dc0753acbf8521ca2e0f137b4578b917b10cf24" + integrity sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g== dependencies: isarray "0.0.1" diff --git a/util/app/discovery/discovery.go b/util/app/discovery/discovery.go index df80e3bf987c2..9f477e3a35a23 100644 --- a/util/app/discovery/discovery.go +++ b/util/app/discovery/discovery.go @@ -170,12 +170,17 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil cfg, err := cmpClient.CheckPluginConfiguration(ctx, &empty.Empty{}) if err != nil { log.Errorf("error checking plugin configuration %s, %v", fileName, err) + io.Close(conn) return nil, nil, false } - // if discovery is not configured, return the client without further checks if !cfg.IsDiscoveryConfigured { - return conn, cmpClient, true + // If discovery isn't configured but the plugin is named, then the plugin supports the repo. + if namedPlugin { + return conn, cmpClient, true + } + io.Close(conn) + return nil, nil, false } isSupported, isDiscoveryEnabled, err := matchRepositoryCMP(ctx, appPath, repoPath, cmpClient, env, tarExcludedGlobs) diff --git a/util/app/path/path.go b/util/app/path/path.go index 2dc3af09e7322..66f4fe1c02678 100644 --- a/util/app/path/path.go +++ b/util/app/path/path.go @@ -1,6 +1,7 @@ package path import ( + "errors" "fmt" "os" "path/filepath" @@ -51,6 +52,11 @@ func CheckOutOfBoundsSymlinks(basePath string) error { } return filepath.Walk(absBasePath, func(path string, info os.FileInfo, err error) error { if err != nil { + // Ignore "no such file or directory" errors than can happen with + // temporary files such as .git/*.lock + if errors.Is(err, os.ErrNotExist) { + return nil + } return fmt.Errorf("failed to walk for symlinks in %s: %w", absBasePath, err) } if files.IsSymlink(info) { diff --git a/util/argo/argo.go b/util/argo/argo.go index 973a29418b309..1119d06271728 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -231,6 +231,7 @@ func RefreshApp(appIf v1alpha1.ApplicationInterface, name string, refreshType ar "metadata": map[string]interface{}{ "annotations": map[string]string{ argoappv1.AnnotationKeyRefresh: string(refreshType), + argoappv1.AnnotationKeyHydrate: "normal", }, }, } @@ -329,7 +330,10 @@ func ValidateRepo( }) return conditions, nil } - config := cluster.RESTConfig() + config, err := cluster.RESTConfig() + if err != nil { + return nil, fmt.Errorf("error getting cluster REST config: %w", err) + } // nolint:staticcheck cluster.ServerVersion, err = kubectl.GetServerVersion(config) if err != nil { @@ -414,6 +418,12 @@ func validateRepo(ctx context.Context, } } + // If using the source hydrator, check the dry source instead of the sync source, since the sync source branch may + // not exist yet. + if app.Spec.SourceHydrator != nil { + sources = []argoappv1.ApplicationSource{app.Spec.SourceHydrator.GetDrySource()} + } + refSources, err := GetRefSources(ctx, sources, app.Spec.Project, db.GetRepository, []string{}, false) if err != nil { return nil, fmt.Errorf("error getting ref sources: %w", err) @@ -423,8 +433,7 @@ func validateRepo(ctx context.Context, db, permittedHelmRepos, helmOptions, - app.Name, - app.Spec.Destination, + app, proj, sources, repoClient, @@ -434,7 +443,6 @@ func validateRepo(ctx context.Context, permittedHelmCredentials, enabledSourceTypes, settingsMgr, - app.Spec.HasMultipleSources(), refSources)...) return conditions, nil @@ -484,16 +492,18 @@ func GetRefSources(ctx context.Context, sources argoappv1.ApplicationSources, pr return refSources, nil } -// ValidateDestination sets the 'Server' value of the ApplicationDestination, if it is not set. +// ValidateDestination sets the 'Server' or the `Name` value of the ApplicationDestination, if it is not set. // NOTE: this function WILL write to the object pointed to by the 'dest' parameter. -// // If an ApplicationDestination has a Name field, but has an empty Server (URL) field, // ValidationDestination will look up the cluster by name (to get the server URL), and -// set the corresponding Server field value. +// set the corresponding Server field value. Same goes for the opposite case. // // It also checks: // - If we used both name and server then we return an invalid spec error func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestination, db db.ArgoDB) error { + if dest.IsServerInferred() && dest.IsNameInferred() { + return fmt.Errorf("application destination can't have both name and server inferred: %s %s", dest.Name, dest.Server) + } if dest.Name != "" { if dest.Server == "" { server, err := getDestinationServer(ctx, db, dest.Name) @@ -504,9 +514,20 @@ func ValidateDestination(ctx context.Context, dest *argoappv1.ApplicationDestina return fmt.Errorf("application references destination cluster %s which does not exist", dest.Name) } dest.SetInferredServer(server) - } else if !dest.IsServerInferred() { + } else if !dest.IsServerInferred() && !dest.IsNameInferred() { return fmt.Errorf("application destination can't have both name and server defined: %s %s", dest.Name, dest.Server) } + } else if dest.Server != "" { + if dest.Name == "" { + serverName, err := getDestinationServerName(ctx, db, dest.Server) + if err != nil { + return fmt.Errorf("unable to find destination server: %w", err) + } + if serverName == "" { + return fmt.Errorf("application references destination cluster %s which does not exist", dest.Server) + } + dest.SetInferredName(serverName) + } } return nil } @@ -541,11 +562,46 @@ func validateSourcePermissions(source argoappv1.ApplicationSource, hasMultipleSo return conditions } +func validateSourceHydrator(hydrator *argoappv1.SourceHydrator) []argoappv1.ApplicationCondition { + var conditions []argoappv1.ApplicationCondition + if hydrator.DrySource.RepoURL == "" { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: "spec.sourceHydrator.drySource.repoURL is required", + }) + } + if hydrator.SyncSource.TargetBranch == "" { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: "spec.sourceHydrator.syncSource.targetBranch is required", + }) + } + if hydrator.HydrateTo != nil && hydrator.HydrateTo.TargetBranch == "" { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: "when spec.sourceHydrator.hydrateTo is set, spec.sourceHydrator.hydrateTo.path is required", + }) + } + return conditions +} + // ValidatePermissions ensures that the referenced cluster has been added to Argo CD and the app source repo and destination namespace/cluster are permitted in app project func ValidatePermissions(ctx context.Context, spec *argoappv1.ApplicationSpec, proj *argoappv1.AppProject, db db.ArgoDB) ([]argoappv1.ApplicationCondition, error) { conditions := make([]argoappv1.ApplicationCondition, 0) - if spec.HasMultipleSources() { + if spec.SourceHydrator != nil { + condition := validateSourceHydrator(spec.SourceHydrator) + if len(condition) > 0 { + conditions = append(conditions, condition...) + return conditions, nil + } + if !proj.IsSourcePermitted(spec.SourceHydrator.GetDrySource()) { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("application repo %s is not permitted in project '%s'", spec.GetSource().RepoURL, spec.Project), + }) + } + } else if spec.HasMultipleSources() { for _, source := range spec.Sources { condition := validateSourcePermissions(source, spec.HasMultipleSources()) if len(condition) > 0 { @@ -706,8 +762,7 @@ func verifyGenerateManifests( db db.ArgoDB, helmRepos argoappv1.Repositories, helmOptions *argoappv1.HelmOptions, - name string, - dest argoappv1.ApplicationDestination, + app *argoappv1.Application, proj *argoappv1.AppProject, sources []argoappv1.ApplicationSource, repoClient apiclient.RepoServerServiceClient, @@ -716,11 +771,10 @@ func verifyGenerateManifests( repositoryCredentials []*argoappv1.RepoCreds, enableGenerateManifests map[string]bool, settingsMgr *settings.SettingsManager, - hasMultipleSources bool, refSources argoappv1.RefTargetRevisionMapping, ) []argoappv1.ApplicationCondition { var conditions []argoappv1.ApplicationCondition - if dest.Server == "" { + if app.Spec.Destination.Server == "" { conditions = append(conditions, argoappv1.ApplicationCondition{ Type: argoappv1.ApplicationConditionInvalidSpecError, Message: errDestinationMissing, @@ -753,6 +807,14 @@ func verifyGenerateManifests( }) continue } + installationID, err := settingsMgr.GetInstallationID() + if err != nil { + conditions = append(conditions, argoappv1.ApplicationCondition{ + Type: argoappv1.ApplicationConditionInvalidSpecError, + Message: fmt.Sprintf("Error getting installation ID: %v", err), + }) + continue + } req := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{ Repo: source.RepoURL, @@ -761,23 +823,25 @@ func verifyGenerateManifests( Proxy: repoRes.Proxy, NoProxy: repoRes.NoProxy, }, - Repos: helmRepos, - Revision: source.TargetRevision, - AppName: name, - Namespace: dest.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: kubeVersion, - ApiVersions: apiVersions, - HelmOptions: helmOptions, - HelmRepoCreds: repositoryCredentials, - TrackingMethod: string(GetTrackingMethod(settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - NoRevisionCache: true, - HasMultipleSources: hasMultipleSources, - RefSources: refSources, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repos: helmRepos, + Revision: source.TargetRevision, + AppName: app.Name, + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: kubeVersion, + ApiVersions: apiVersions, + HelmOptions: helmOptions, + HelmRepoCreds: repositoryCredentials, + TrackingMethod: string(GetTrackingMethod(settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + NoRevisionCache: true, + HasMultipleSources: app.Spec.HasMultipleSources(), + RefSources: refSources, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: app.GetAnnotation(argoappv1.AnnotationKeyManifestGeneratePaths), + InstallationID: installationID, } req.Repo.CopyCredentialsFromRepo(repoRes) req.Repo.CopySettingsFrom(repoRes) @@ -950,6 +1014,22 @@ func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) return servers[0], nil } +func getDestinationServerName(ctx context.Context, db db.ArgoDB, server string) (string, error) { + if db == nil { + return "", fmt.Errorf("there are no clusters registered in the database") + } + + cluster, err := db.GetCluster(ctx, server) + if err != nil { + return "", fmt.Errorf("error getting cluster name by server %q: %w", server, err) + } + + if cluster.Name == "" { + return "", fmt.Errorf("there are no clusters with this URL: %s", server) + } + return cluster.Name, nil +} + func GetGlobalProjects(proj *argoappv1.AppProject, projLister applicationsv1.AppProjectLister, settingsManager *settings.SettingsManager) []*argoappv1.AppProject { gps, err := settingsManager.GetGlobalProjectsSettings() globalProjects := make([]*argoappv1.AppProject, 0) @@ -1029,7 +1109,7 @@ func GenerateSpecIsDifferentErrorMessage(entity string, a, b interface{}) string if len(difference) == 0 { return basicMsg } - return fmt.Sprintf("%s; difference in keys \"%s\"", basicMsg, strings.Join(difference, ",")) + return fmt.Sprintf("%s; difference in keys %q", basicMsg, strings.Join(difference, ",")) } func GetDifferentPathsBetweenStructs(a, b interface{}) ([]string, error) { diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go index b2c684c660c1f..420eee9b7471c 100644 --- a/util/argo/argo_test.go +++ b/util/argo/argo_test.go @@ -78,7 +78,7 @@ func TestGetAppProjectWithNoProjDefined(t *testing.T) { go informer.Run(ctx.Done()) cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) - kubeClient := fake.NewSimpleClientset(&cm) + kubeClient := fake.NewClientset(&cm) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) argoDB := db.NewDB("default", settingsMgr, kubeClient) proj, err := GetAppProject(&testApp, applisters.NewAppProjectLister(informer.GetIndexer()), namespace, settingsMgr, argoDB, ctx) @@ -446,7 +446,7 @@ func TestValidateRepo(t *testing.T) { }, } - kubeClient := fake.NewSimpleClientset(&cm) + kubeClient := fake.NewClientset(&cm) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) conditions, err := ValidateRepo(context.Background(), app, repoClientSet, db, &kubetest.MockKubectlCmd{Version: kubeVersion, APIResources: apiResources}, proj, settingsMgr) @@ -702,7 +702,7 @@ func TestValidatePermissions(t *testing.T) { SourceRepos: []string{"http://some/where/else"}, }, } - cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"} + cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) @@ -735,7 +735,7 @@ func TestValidatePermissions(t *testing.T) { SourceRepos: []string{"http://some/where"}, }, } - cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"} + cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) @@ -773,7 +773,7 @@ func TestValidatePermissions(t *testing.T) { conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) require.NoError(t, err) assert.Len(t, conditions, 1) - assert.Contains(t, conditions[0].Message, "has not been configured") + assert.Contains(t, conditions[0].Message, "unable to find destination server") }) t.Run("Destination cluster name does not exist", func(t *testing.T) { @@ -834,8 +834,10 @@ func TestValidatePermissions(t *testing.T) { } db := &dbmocks.ArgoDB{} db.On("GetCluster", context.Background(), spec.Destination.Server).Return(nil, fmt.Errorf("Unknown error occurred")) - _, err := ValidatePermissions(context.Background(), &spec, &proj, db) - require.Error(t, err) + conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) + require.NoError(t, err) + assert.Len(t, conditions, 1) + assert.Contains(t, conditions[0].Message, "Unknown error occurred") }) t.Run("Destination cluster name resolves to valid server", func(t *testing.T) { @@ -893,8 +895,7 @@ func TestSetAppOperations(t *testing.T) { } appIf := appclientset.NewSimpleClientset(&a).ArgoprojV1alpha1().Applications("default") app, err := SetAppOperation(appIf, "someapp", &argoappv1.Operation{Sync: &argoappv1.SyncOperation{Revision: "aaa"}}) - require.Error(t, err) - assert.Contains(t, err.Error(), "operation is already in progress") + require.ErrorContains(t, err, "operation is already in progress") assert.Nil(t, app) }) @@ -907,8 +908,7 @@ func TestSetAppOperations(t *testing.T) { } appIf := appclientset.NewSimpleClientset(&a).ArgoprojV1alpha1().Applications("default") app, err := SetAppOperation(appIf, "someapp", &argoappv1.Operation{Sync: nil}) - require.Error(t, err) - assert.Contains(t, err.Error(), "Operation unspecified") + require.ErrorContains(t, err, "Operation unspecified") assert.Nil(t, app) }) @@ -934,7 +934,7 @@ func TestValidateDestination(t *testing.T) { } appCond := ValidateDestination(context.Background(), &dest, nil) - require.NoError(t, appCond) + require.Error(t, appCond) assert.False(t, dest.IsServerInferred()) }) @@ -973,7 +973,7 @@ func TestValidateDestination(t *testing.T) { db.On("GetClusterServersByName", context.Background(), mock.Anything).Return(nil, fmt.Errorf("an error occurred")) err := ValidateDestination(context.Background(), &dest, db) - assert.Contains(t, err.Error(), "an error occurred") + require.ErrorContains(t, err, "an error occurred") assert.False(t, dest.IsServerInferred()) }) @@ -1422,7 +1422,7 @@ func TestValidatePermissionsMultipleSources(t *testing.T) { SourceRepos: []string{"http://some/where/else"}, }, } - cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443"} + cluster := &argoappv1.Cluster{Server: "https://127.0.0.1:6443", Name: "test"} db := &dbmocks.ArgoDB{} db.On("GetCluster", context.Background(), spec.Destination.Server).Return(cluster, nil) conditions, err := ValidatePermissions(context.Background(), &spec, &proj, db) diff --git a/util/argo/audit_logger_test.go b/util/argo/audit_logger_test.go index a0c5714fb3266..900bf43c4b128 100644 --- a/util/argo/audit_logger_test.go +++ b/util/argo/audit_logger_test.go @@ -36,12 +36,12 @@ func captureLogEntries(run func()) string { } func TestNewAuditLogger(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) + logger := NewAuditLogger("default", fake.NewClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) } func TestLogAppProjEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) + logger := NewAuditLogger("default", fake.NewClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) proj := argoappv1.AppProject{ @@ -82,7 +82,7 @@ func TestLogAppProjEvent(t *testing.T) { } func TestLogAppEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) + logger := NewAuditLogger("default", fake.NewClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) app := argoappv1.Application{ @@ -128,7 +128,7 @@ func TestLogAppEvent(t *testing.T) { } func TestLogResourceEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) + logger := NewAuditLogger("default", fake.NewClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) res := argoappv1.ResourceNode{ diff --git a/util/argo/diff/ignore_test.go b/util/argo/diff/ignore_test.go index d5eacd3a49228..90c7b0464d7b6 100644 --- a/util/argo/diff/ignore_test.go +++ b/util/argo/diff/ignore_test.go @@ -51,6 +51,7 @@ func TestIgnoreDiffConfig_HasIgnoreDifference(t *testing.T) { assert.True(t, ok) assert.NotNil(t, actual) assert.Equal(t, expectedManagedFields, actual.ManagedFieldsManagers) + // nolint:testifylint assert.Equal(t, expectedJSONPointers, actual.JSONPointers) assert.Equal(t, expectedJQExpression, actual.JQPathExpressions) }) @@ -72,6 +73,7 @@ func TestIgnoreDiffConfig_HasIgnoreDifference(t *testing.T) { assert.True(t, ok) assert.NotNil(t, actual) assert.Equal(t, expectedManagedFields, actual.ManagedFieldsManagers) + // nolint:testifylint assert.Equal(t, expectedJSONPointers, actual.JSONPointers) assert.Equal(t, expectedJQExpression, actual.JQPathExpressions) }) diff --git a/util/argo/resource_tracking.go b/util/argo/resource_tracking.go index e904f2aa1d466..bd951ebb29d9c 100644 --- a/util/argo/resource_tracking.go +++ b/util/argo/resource_tracking.go @@ -29,9 +29,9 @@ var ( // ResourceTracking defines methods which allow setup and retrieve tracking information to resource type ResourceTracking interface { - GetAppName(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod) string - GetAppInstance(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod) *AppInstanceValue - SetAppInstance(un *unstructured.Unstructured, key, val, namespace string, trackingMethod v1alpha1.TrackingMethod) error + GetAppName(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, installationID string) string + GetAppInstance(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, installationID string) *AppInstanceValue + SetAppInstance(un *unstructured.Unstructured, key, val, namespace string, trackingMethod v1alpha1.TrackingMethod, instanceID string) error BuildAppInstanceValue(value AppInstanceValue) string ParseAppInstanceValue(value string) (*AppInstanceValue, error) Normalize(config, live *unstructured.Unstructured, labelKey, trackingMethod string) error @@ -65,7 +65,10 @@ func IsOldTrackingMethod(trackingMethod string) bool { return trackingMethod == "" || trackingMethod == string(TrackingMethodLabel) } -func (rt *resourceTracking) getAppInstanceValue(un *unstructured.Unstructured) *AppInstanceValue { +func (rt *resourceTracking) getAppInstanceValue(un *unstructured.Unstructured, installationID string) *AppInstanceValue { + if installationID != "" && un.GetAnnotations() == nil || un.GetAnnotations()[common.AnnotationInstallationID] != installationID { + return nil + } appInstanceAnnotation, err := argokube.GetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance) if err != nil { return nil @@ -78,9 +81,9 @@ func (rt *resourceTracking) getAppInstanceValue(un *unstructured.Unstructured) * } // GetAppName retrieve application name base on tracking method -func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod) string { +func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, instanceID string) string { retrieveAppInstanceValue := func() string { - value := rt.getAppInstanceValue(un) + value := rt.getAppInstanceValue(un, instanceID) if value != nil { return value.ApplicationName } @@ -109,10 +112,10 @@ func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string // GetAppInstance returns the representation of the app instance annotation. // If the tracking method does not support metadata, or the annotation could // not be parsed, it returns nil. -func (rt *resourceTracking) GetAppInstance(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod) *AppInstanceValue { +func (rt *resourceTracking) GetAppInstance(un *unstructured.Unstructured, key string, trackingMethod v1alpha1.TrackingMethod, instanceID string) *AppInstanceValue { switch trackingMethod { case TrackingMethodAnnotation, TrackingMethodAnnotationAndLabel: - return rt.getAppInstanceValue(un) + return rt.getAppInstanceValue(un, instanceID) default: return nil } @@ -138,9 +141,18 @@ func UnstructuredToAppInstanceValue(un *unstructured.Unstructured, appName, name } // SetAppInstance set label/annotation base on tracking method -func (rt *resourceTracking) SetAppInstance(un *unstructured.Unstructured, key, val, namespace string, trackingMethod v1alpha1.TrackingMethod) error { +func (rt *resourceTracking) SetAppInstance(un *unstructured.Unstructured, key, val, namespace string, trackingMethod v1alpha1.TrackingMethod, instanceID string) error { setAppInstanceAnnotation := func() error { appInstanceValue := UnstructuredToAppInstanceValue(un, val, namespace) + if instanceID != "" { + if err := argokube.SetAppInstanceAnnotation(un, common.AnnotationInstallationID, instanceID); err != nil { + return err + } + } else { + if err := argokube.RemoveAnnotation(un, common.AnnotationInstallationID); err != nil { + return err + } + } return argokube.SetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance, rt.BuildAppInstanceValue(appInstanceValue)) } switch trackingMethod { diff --git a/util/argo/resource_tracking_test.go b/util/argo/resource_tracking_test.go index 3c747edf69fcb..1616c1abce9a6 100644 --- a/util/argo/resource_tracking_test.go +++ b/util/argo/resource_tracking_test.go @@ -24,9 +24,9 @@ func TestSetAppInstanceLabel(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel) + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodLabel) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodLabel, "") assert.Equal(t, "my-app", app) } @@ -40,10 +40,10 @@ func TestSetAppInstanceAnnotation(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", TrackingMethodAnnotation) + err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", TrackingMethodAnnotation, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, TrackingMethodAnnotation) + app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, TrackingMethodAnnotation, "") assert.Equal(t, "my-app", app) } @@ -56,10 +56,10 @@ func TestSetAppInstanceAnnotationAndLabel(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodAnnotationAndLabel) + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodAnnotationAndLabel, "") require.NoError(t, err) - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "") assert.Equal(t, "my-app", app) } @@ -72,11 +72,11 @@ func TestSetAppInstanceAnnotationAndLabelLongName(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", "", TrackingMethodAnnotationAndLabel) + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", "", TrackingMethodAnnotationAndLabel, "") require.NoError(t, err) // the annotation should still work, so the name from GetAppName should not be truncated - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "") assert.Equal(t, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", app) // the label should be truncated to 63 characters @@ -92,11 +92,11 @@ func TestSetAppInstanceAnnotationAndLabelLongNameBadEnding(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", "", TrackingMethodAnnotationAndLabel) + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", "", TrackingMethodAnnotationAndLabel, "") require.NoError(t, err) // the annotation should still work, so the name from GetAppName should not be truncated - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "") assert.Equal(t, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", app) // the label should be truncated to 63 characters, AND the hyphen should be removed @@ -112,7 +112,7 @@ func TestSetAppInstanceAnnotationAndLabelOutOfBounds(t *testing.T) { resourceTracking := NewResourceTracking() - err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "----------------------------------------------------------------", "", TrackingMethodAnnotationAndLabel) + err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "----------------------------------------------------------------", "", TrackingMethodAnnotationAndLabel, "") // this should error because it can't truncate to a valid value assert.EqualError(t, err, "failed to set app instance label: unable to truncate label to not end with a special character") } @@ -127,7 +127,7 @@ func TestSetAppInstanceAnnotationNotFound(t *testing.T) { resourceTracking := NewResourceTracking() - app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotation) + app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotation, "") assert.Equal(t, "", app) } @@ -172,6 +172,7 @@ func TestParseAppInstanceValueCorrectFormat(t *testing.T) { } func sampleResource(t *testing.T) *unstructured.Unstructured { + t.Helper() yamlBytes, err := os.ReadFile("testdata/svc.yaml") require.NoError(t, err) var obj *unstructured.Unstructured @@ -185,12 +186,12 @@ func TestResourceIdNormalizer_Normalize(t *testing.T) { // live object is a resource that has old style tracking label liveObj := sampleResource(t) - err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel) + err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) // config object is a resource that has new style tracking annotation configObj := sampleResource(t) - err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation) + err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "") require.NoError(t, err) _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)) @@ -208,14 +209,14 @@ func TestResourceIdNormalizer_Normalize_ConfigHasOldLabel(t *testing.T) { // live object is a resource that has old style tracking label liveObj := sampleResource(t) - err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel) + err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) // config object is a resource that has new style tracking annotation configObj := sampleResource(t) - err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation) + err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "") require.NoError(t, err) - err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel) + err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "") require.NoError(t, err) _ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)) diff --git a/reposerver/askpass/askpass.pb.go b/util/askpass/askpass.pb.go similarity index 90% rename from reposerver/askpass/askpass.pb.go rename to util/askpass/askpass.pb.go index d1d2a4612a9ac..c41b7336e741e 100644 --- a/reposerver/askpass/askpass.pb.go +++ b/util/askpass/askpass.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: reposerver/askpass/askpass.proto +// source: util/askpass/askpass.proto package askpass @@ -37,7 +37,7 @@ 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} + return fileDescriptor_1c7c1d31cf056104, []int{0} } func (m *CredentialsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -85,7 +85,7 @@ 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} + return fileDescriptor_1c7c1d31cf056104, []int{1} } func (m *CredentialsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -133,25 +133,25 @@ func init() { proto.RegisterType((*CredentialsResponse)(nil), "askpass.CredentialsResponse") } -func init() { proto.RegisterFile("reposerver/askpass/askpass.proto", fileDescriptor_099f282cab154dba) } +func init() { proto.RegisterFile("util/askpass/askpass.proto", fileDescriptor_1c7c1d31cf056104) } -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, +var fileDescriptor_1c7c1d31cf056104 = []byte{ + // 225 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x2d, 0xc9, 0xcc, + 0xd1, 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, + 0x59, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x51, 0xda, + 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, 0x72, 0x68, 0x25, 0xb1, + 0x81, 0x83, 0xc9, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xcc, 0x96, 0x87, 0x44, 0x01, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -231,7 +231,7 @@ var _AskPassService_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "reposerver/askpass/askpass.proto", + Metadata: "util/askpass/askpass.proto", } func (m *CredentialsRequest) Marshal() (dAtA []byte, err error) { diff --git a/reposerver/askpass/askpass.proto b/util/askpass/askpass.proto similarity index 80% rename from reposerver/askpass/askpass.proto rename to util/askpass/askpass.proto index 4547edc3a0306..f4c3788185d7a 100644 --- a/reposerver/askpass/askpass.proto +++ b/util/askpass/askpass.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/v2/reposerver/askpass"; +option go_package = "github.com/argoproj/argo-cd/v2/util/askpass"; package askpass; diff --git a/reposerver/askpass/common.go b/util/askpass/common.go similarity index 76% rename from reposerver/askpass/common.go rename to util/askpass/common.go index c9757f5878956..2a34cca52c84c 100644 --- a/reposerver/askpass/common.go +++ b/util/askpass/common.go @@ -11,6 +11,8 @@ const ( ASKPASS_NONCE_ENV = "ARGOCD_GIT_ASKPASS_NONCE" // AKSPASS_SOCKET_PATH_ENV is the environment variable that is used to pass the socket path to the askpass script AKSPASS_SOCKET_PATH_ENV = "ARGOCD_ASK_PASS_SOCK" + // CommitServerSocketPath is the path to the socket used by the commit server to communicate with the askpass server + CommitServerSocketPath = "/tmp/commit-server-ask-pass.sock" ) func init() { diff --git a/reposerver/askpass/server.go b/util/askpass/server.go similarity index 61% rename from reposerver/askpass/server.go rename to util/askpass/server.go index 2eb9f89869776..b6a1bbfc48de2 100644 --- a/reposerver/askpass/server.go +++ b/util/askpass/server.go @@ -22,6 +22,20 @@ type Server interface { Run(path string) error } +// server is a gRPC server that provides a way for an external process (usually git) to access credentials without those +// credentials being set directly in the git process's environment. Before invoking git, the caller invokes Add to add a +// new credential, which returns a unique id. The caller then sets the GIT_ASKPASS environment variable to the path of +// the argocd-git-ask-pass binary and sets the ASKPASS_NONCE environment variable to the id. When git needs credentials, +// it will invoke the argocd-git-ask-pass binary, which will use the ASKPASS_NONCE to look up the credentials and return +// them to git. After the git process completes, the caller should invoke Remove to remove the credential. +// +// This is meant to solve a class of problems that was demonstrated by an old bug in Kustomize. We needed to enable +// Kustomize to invoke git to fetch a private repository. But Kustomize had a bug that allowed a user to dump the +// environment variables of the process into manifests, which would expose the credentials. Kustomize eventually fixed +// the bug. But to prevent this from happening again, we now only set the ASKPASS_NONCE environment variable instead of +// directly passing the git credentials via environment variables. Even if the nonce leaks, 1) the user probably doesn't +// have access to the server to look up the corresponding git credentials, and 2) the nonce should be deleted from +// the server before the user even sees the manifests. type server struct { lock sync.Mutex creds map[string]Creds diff --git a/reposerver/askpass/server_test.go b/util/askpass/server_test.go similarity index 100% rename from reposerver/askpass/server_test.go rename to util/askpass/server_test.go diff --git a/util/cache/cache_test.go b/util/cache/cache_test.go index 0a156cedeeb0d..921b2b1dc1b9b 100644 --- a/util/cache/cache_test.go +++ b/util/cache/cache_test.go @@ -74,11 +74,9 @@ func TestCacheClient(t *testing.T) { }) t.Run("Check for nil items", func(t *testing.T) { err := cache.SetItem("foo", nil, &CacheActionOpts{Expiration: 0, Delete: true}) - require.Error(t, err) - assert.Contains(t, err.Error(), "cannot set nil item") + require.ErrorContains(t, err, "cannot set nil item") err = cache.GetItem("foo", nil) - require.Error(t, err) - assert.Contains(t, err.Error(), "cannot get item") + assert.ErrorContains(t, err, "cannot get item") }) } } diff --git a/util/cache/redis.go b/util/cache/redis.go index 5a832fd6ccd45..2c938b6998bb7 100644 --- a/util/cache/redis.go +++ b/util/cache/redis.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "net" + "sync" "time" ioutil "github.com/argoproj/argo-cd/v2/util/io" @@ -200,6 +201,11 @@ func (redisHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.Proce } // CollectMetrics add transport wrapper that pushes metrics into the specified metrics registry -func CollectMetrics(client *redis.Client, registry MetricsRegistry) { +// Lock should be shared between functions that can add/process a Redis hook. +func CollectMetrics(client *redis.Client, registry MetricsRegistry, lock *sync.RWMutex) { + if lock != nil { + lock.Lock() + defer lock.Unlock() + } client.AddHook(&redisHook{registry: registry}) } diff --git a/util/cache/redis_test.go b/util/cache/redis_test.go index e0314cefaf63a..8cda6d8086e74 100644 --- a/util/cache/redis_test.go +++ b/util/cache/redis_test.go @@ -90,8 +90,7 @@ func TestRedisSetCache(t *testing.T) { var res string client := NewRedisCache(redis.NewClient(&redis.Options{Addr: mr.Addr()}), 10*time.Second, RedisCompressionNone) err = client.Get("foo", &res) - require.Error(t, err) - assert.Contains(t, err.Error(), "cache: key is missing") + assert.ErrorContains(t, err, "cache: key is missing") }) } @@ -137,8 +136,8 @@ func TestRedisMetrics(t *testing.T) { ms := NewMockMetricsServer() redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()}) faultyRedisClient := redis.NewClient(&redis.Options{Addr: "invalidredishost.invalid:12345"}) - CollectMetrics(redisClient, ms) - CollectMetrics(faultyRedisClient, ms) + CollectMetrics(redisClient, ms, nil) + CollectMetrics(faultyRedisClient, ms, nil) client := NewRedisCache(redisClient, 60*time.Second, RedisCompressionNone) faultyClient := NewRedisCache(faultyRedisClient, 60*time.Second, RedisCompressionNone) diff --git a/util/cert/cert_test.go b/util/cert/cert_test.go index a9fb4c4810eb2..cfc4b4385dd07 100644 --- a/util/cert/cert_test.go +++ b/util/cert/cert_test.go @@ -505,7 +505,7 @@ func TestGetCertificateForConnect(t *testing.T) { certs, err := GetCertificateForConnect("127.0.0.1") require.Error(t, err) assert.Empty(t, certs) - assert.Contains(t, err.Error(), "no certificates found") + assert.ErrorContains(t, err, "no certificates found") }) } diff --git a/util/cmp/stream.go b/util/cmp/stream.go index 429bba446d0a7..d7f080004d6f4 100644 --- a/util/cmp/stream.go +++ b/util/cmp/stream.go @@ -84,12 +84,12 @@ func WithTarDoneChan(ch chan<- bool) SenderOption { } } -// SendRepoStream will compress the files under the given repoPath and send +// SendRepoStream will compress the files under the given rootPath and send // them using the plugin stream sender. -func SendRepoStream(ctx context.Context, appPath, repoPath string, sender StreamSender, env []string, excludedGlobs []string, opts ...SenderOption) error { +func SendRepoStream(ctx context.Context, appPath, rootPath string, sender StreamSender, env []string, excludedGlobs []string, opts ...SenderOption) error { opt := newSenderOption(opts...) - tgz, mr, err := GetCompressedRepoAndMetadata(repoPath, appPath, env, excludedGlobs, opt) + tgz, mr, err := GetCompressedRepoAndMetadata(rootPath, appPath, env, excludedGlobs, opt) if err != nil { return err } @@ -107,14 +107,14 @@ func SendRepoStream(ctx context.Context, appPath, repoPath string, sender Stream return nil } -func GetCompressedRepoAndMetadata(repoPath string, appPath string, env []string, excludedGlobs []string, opt *senderOption) (*os.File, *pluginclient.AppStreamRequest, error) { - // compress all files in repoPath in tgz - tgz, filesWritten, checksum, err := tgzstream.CompressFiles(repoPath, nil, excludedGlobs) +func GetCompressedRepoAndMetadata(rootPath string, appPath string, env []string, excludedGlobs []string, opt *senderOption) (*os.File, *pluginclient.AppStreamRequest, error) { + // compress all files in rootPath in tgz + tgz, filesWritten, checksum, err := tgzstream.CompressFiles(rootPath, nil, excludedGlobs) if err != nil { return nil, nil, fmt.Errorf("error compressing repo files: %w", err) } if filesWritten == 0 { - return nil, nil, fmt.Errorf("no files to send") + return nil, nil, fmt.Errorf("no files to send(%s)", rootPath) } if opt != nil && opt.tarDoneChan != nil { opt.tarDoneChan <- true @@ -125,7 +125,7 @@ func GetCompressedRepoAndMetadata(repoPath string, appPath string, env []string, if err != nil { return nil, nil, fmt.Errorf("error getting tgz stat: %w", err) } - appRelPath, err := files.RelativePath(appPath, repoPath) + appRelPath, err := files.RelativePath(appPath, rootPath) if err != nil { return nil, nil, fmt.Errorf("error building app relative path: %w", err) } diff --git a/util/cmp/stream_test.go b/util/cmp/stream_test.go index fa176f6b87be1..393cf5d1679a2 100644 --- a/util/cmp/stream_test.go +++ b/util/cmp/stream_test.go @@ -94,5 +94,6 @@ func (m *streamMock) sendFile(ctx context.Context, t *testing.T, basedir string, // getTestDataDir will return the full path of the testdata dir // under the running test folder. func getTestDataDir(t *testing.T) string { + t.Helper() return filepath.Join(test.GetTestDir(t), "testdata") } diff --git a/util/collections/maps.go b/util/collections/maps.go index d7a42943674b7..35f2f07e0e3b7 100644 --- a/util/collections/maps.go +++ b/util/collections/maps.go @@ -1,36 +1,16 @@ package collections -import "reflect" +import "maps" -// CopyStringMap creates copy of a string map -func CopyStringMap(in map[string]string) map[string]string { - out := map[string]string{} - for k, v := range in { - out[k] = v - } - return out -} - -// StringMapsEqual compares two string maps assuming that nil and empty map are considered equal -func StringMapsEqual(first map[string]string, second map[string]string) bool { - if first == nil { - first = map[string]string{} - } - if second == nil { - second = map[string]string{} - } - return reflect.DeepEqual(first, second) -} - -func MergeStringMaps(items ...map[string]string) map[string]string { - res := make(map[string]string) +// Merge takes a collection of maps and returns a single map, where by items are merged of all given sets. +// If any keys overlap, Then the last specified key takes precedence. +// Example: +// +// data := collections.Merge(map[string]string{"foo": "bar1", "baz": "bar1"}, map[string]string{"foo": "bar2"}) // returns: map[string]string{"foo": "bar2", "empty": "bar1"} +func Merge[K comparable, V any](items ...map[K]V) map[K]V { + res := make(map[K]V) for _, m := range items { - if m == nil { - continue - } - for k, v := range m { - res[k] = v - } + maps.Copy(res, m) } return res } diff --git a/util/collections/maps_test.go b/util/collections/maps_test.go index 39cd7bf0b2b96..25c241dbf3b63 100644 --- a/util/collections/maps_test.go +++ b/util/collections/maps_test.go @@ -6,20 +6,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestCopyStringMap(t *testing.T) { - out := CopyStringMap(map[string]string{"foo": "bar"}) - assert.Equal(t, map[string]string{"foo": "bar"}, out) -} - -func TestStringMapsEqual(t *testing.T) { - assert.True(t, StringMapsEqual(nil, nil)) - assert.True(t, StringMapsEqual(nil, map[string]string{})) - assert.True(t, StringMapsEqual(map[string]string{}, nil)) - assert.True(t, StringMapsEqual(map[string]string{"foo": "bar"}, map[string]string{"foo": "bar"})) - assert.False(t, StringMapsEqual(map[string]string{"foo": "bar"}, nil)) - assert.False(t, StringMapsEqual(map[string]string{"foo": "bar"}, map[string]string{"foo": "bar1"})) -} - func TestMergeStringMaps(t *testing.T) { tests := []struct { name string @@ -73,7 +59,7 @@ func TestMergeStringMaps(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, MergeStringMaps(tt.args...), "MergeStringMaps(%v)", tt.args) + assert.Equalf(t, tt.want, Merge(tt.args...), "Merge[string, string](%v)", tt.args) }) } } diff --git a/util/config/env.go b/util/config/env.go index d2007fba6af49..f5576e649ee0a 100644 --- a/util/config/env.go +++ b/util/config/env.go @@ -14,13 +14,13 @@ import ( var flags map[string]string func init() { - err := loadFlags() + err := LoadFlags() if err != nil { log.Fatal(err) } } -func loadFlags() error { +func LoadFlags() error { flags = make(map[string]string) opts, err := shellquote.Split(os.Getenv("ARGOCD_OPTS")) diff --git a/util/config/env_test.go b/util/config/env_test.go index 63db6974916e6..6fdbbee0d23d0 100644 --- a/util/config/env_test.go +++ b/util/config/env_test.go @@ -7,13 +7,15 @@ import ( ) func loadOpts(t *testing.T, opts string) { + t.Helper() t.Setenv("ARGOCD_OPTS", opts) - assert.NoError(t, loadFlags()) + assert.NoError(t, LoadFlags()) } func loadInvalidOpts(t *testing.T, opts string) { + t.Helper() t.Setenv("ARGOCD_OPTS", opts) - assert.Error(t, loadFlags()) + assert.Error(t, LoadFlags()) } func TestNilOpts(t *testing.T) { diff --git a/util/db/certificate_test.go b/util/db/certificate_test.go index df4ba7aba621d..62358bcd15b3b 100644 --- a/util/db/certificate_test.go +++ b/util/db/certificate_test.go @@ -283,7 +283,7 @@ func getCertClientset() *fake.Clientset { }, } - return fake.NewSimpleClientset([]runtime.Object{&cm, &sshCM, &tlsCM}...) + return fake.NewClientset([]runtime.Object{&cm, &sshCM, &tlsCM}...) } func Test_ListCertificate(t *testing.T) { diff --git a/util/db/cluster.go b/util/db/cluster.go index cee8f7cd43617..4ce9bdbd37aa3 100644 --- a/util/db/cluster.go +++ b/util/db/cluster.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "maps" "strconv" "strings" "sync" @@ -20,7 +21,6 @@ import ( "github.com/argoproj/argo-cd/v2/common" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/util/collections" "github.com/argoproj/argo-cd/v2/util/settings" ) @@ -405,12 +405,12 @@ func SecretToCluster(s *apiv1.Secret) (*appv1.Cluster, error) { // copy labels and annotations excluding system ones labels := map[string]string{} if s.Labels != nil { - labels = collections.CopyStringMap(s.Labels) + labels = maps.Clone(s.Labels) delete(labels, common.LabelKeySecretType) } annotations := map[string]string{} if s.Annotations != nil { - annotations = collections.CopyStringMap(s.Annotations) + annotations = maps.Clone(s.Annotations) // delete system annotations delete(annotations, apiv1.LastAppliedConfigAnnotation) delete(annotations, common.AnnotationKeyManagedBy) diff --git a/util/db/cluster_norace_test.go b/util/db/cluster_norace_test.go index 3386172c3a857..c26cfbf8b42f6 100644 --- a/util/db/cluster_norace_test.go +++ b/util/db/cluster_norace_test.go @@ -46,7 +46,7 @@ func TestWatchClusters_CreateRemoveCluster(t *testing.T) { "server.secretkey": nil, }, } - kubeclientset := fake.NewSimpleClientset(emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ @@ -101,7 +101,7 @@ func TestWatchClusters_LocalClusterModifications(t *testing.T) { "server.secretkey": nil, }, } - kubeclientset := fake.NewSimpleClientset(emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(emptyArgoCDConfigMap, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) runWatchTest(t, db, []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster){ diff --git a/util/db/cluster_test.go b/util/db/cluster_test.go index b430db851664d..fc3da404e891a 100644 --- a/util/db/cluster_test.go +++ b/util/db/cluster_test.go @@ -172,7 +172,7 @@ func Test_secretToCluster_InvalidConfig(t *testing.T) { } func TestUpdateCluster(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(&v1.Secret{ + kubeclientset := fake.NewClientset(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -202,7 +202,7 @@ func TestUpdateCluster(t *testing.T) { } func TestDeleteUnknownCluster(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(&v1.Secret{ + kubeclientset := fake.NewClientset(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "mycluster", Namespace: fakeNamespace, @@ -244,7 +244,7 @@ func TestRejectCreationForInClusterWhenDisabled(t *testing.T) { "server.secretkey": nil, }, } - kubeclientset := fake.NewSimpleClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) + kubeclientset := fake.NewClientset(argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) _, err := db.CreateCluster(context.Background(), &appv1.Cluster{ @@ -255,6 +255,7 @@ func TestRejectCreationForInClusterWhenDisabled(t *testing.T) { } func runWatchTest(t *testing.T, db ArgoDB, actions []func(old *v1alpha1.Cluster, new *v1alpha1.Cluster)) { + t.Helper() ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -370,7 +371,7 @@ func TestListClusters(t *testing.T) { } t.Run("Valid clusters", func(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) @@ -380,7 +381,7 @@ func TestListClusters(t *testing.T) { }) t.Run("Cluster list with invalid cluster", func(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, invalidSecret, emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, secretForServerWithExternalClusterAddr, invalidSecret, emptyArgoCDConfigMap, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) @@ -390,7 +391,7 @@ func TestListClusters(t *testing.T) { }) t.Run("Implicit in-cluster secret", func(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) + kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, emptyArgoCDConfigMap, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) @@ -401,7 +402,7 @@ func TestListClusters(t *testing.T) { }) t.Run("ListClusters() should not add the cluster with in-cluster server address since in-cluster is disabled", func(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(secretForServerWithInClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) + kubeclientset := fake.NewClientset(secretForServerWithInClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) @@ -411,7 +412,7 @@ func TestListClusters(t *testing.T) { }) t.Run("ListClusters() should add this cluster since it does not contain in-cluster server address even though in-cluster is disabled", func(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(secretForServerWithExternalClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) + kubeclientset := fake.NewClientset(secretForServerWithExternalClusterAddr, argoCDConfigMapWithInClusterServerAddressDisabled, argoCDSecret) settingsManager := settings.NewSettingsManager(context.Background(), kubeclientset, fakeNamespace) db := NewDB(fakeNamespace, settingsManager, kubeclientset) @@ -420,3 +421,66 @@ func TestListClusters(t *testing.T) { assert.Len(t, clusters.Items, 1) }) } + +// TestClusterRaceConditionClusterSecrets reproduces a race condition +// on the cluster secrets. The test isn't asserting anything because +// before the fix it would cause a panic from concurrent map iteration and map write +func TestClusterRaceConditionClusterSecrets(t *testing.T) { + clusterSecret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mycluster", + Namespace: "default", + Labels: map[string]string{ + common.LabelKeySecretType: common.LabelValueSecretTypeCluster, + }, + }, + Data: map[string][]byte{ + "server": []byte("http://mycluster"), + "config": []byte("{}"), + }, + } + kubeClient := fake.NewClientset( + &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: common.ArgoCDConfigMapName, + Namespace: "default", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "argocd", + }, + }, + Data: map[string]string{}, + }, + &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: common.ArgoCDSecretName, + Namespace: "default", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "argocd", + }, + }, + Data: map[string][]byte{ + "admin.password": nil, + "server.secretkey": nil, + }, + }, + clusterSecret, + ) + settingsManager := settings.NewSettingsManager(context.Background(), kubeClient, "default") + db := NewDB("default", settingsManager, kubeClient) + cluster, _ := SecretToCluster(clusterSecret) + go func() { + for { + // create a copy so we dont act on the same argo cluster + clusterCopy := cluster.DeepCopy() + _, _ = db.UpdateCluster(context.Background(), clusterCopy) + } + }() + // yes, we will take 15 seconds to run this test + // but it reliably triggered the race condition + for i := 0; i < 30; i++ { + // create a copy so we dont act on the same argo cluster + clusterCopy := cluster.DeepCopy() + _, _ = db.UpdateCluster(context.Background(), clusterCopy) + time.Sleep(time.Millisecond * 500) + } +} diff --git a/util/db/db.go b/util/db/db.go index 34982f8c37806..f0f88d44d338d 100644 --- a/util/db/db.go +++ b/util/db/db.go @@ -47,6 +47,8 @@ type ArgoDB interface { // ListRepositories lists repositories ListRepositories(ctx context.Context) ([]*appv1.Repository, error) + // ListWriteRepositories lists repositories from write credentials + ListWriteRepositories(ctx context.Context) ([]*appv1.Repository, error) // CreateRepository creates a repository CreateRepository(ctx context.Context, r *appv1.Repository) (*appv1.Repository, error) @@ -61,6 +63,19 @@ type ArgoDB interface { // DeleteRepository deletes a repository from config DeleteRepository(ctx context.Context, name, project string) error + // CreateWriteRepository creates a repository with write credentials + CreateWriteRepository(ctx context.Context, r *appv1.Repository) (*appv1.Repository, error) + // GetWriteRepository returns a repository by URL with write credentials + GetWriteRepository(ctx context.Context, url, project string) (*appv1.Repository, error) + // GetProjectWriteRepositories returns project scoped repositories from write credentials by given project name + GetProjectWriteRepositories(ctx context.Context, project string) ([]*appv1.Repository, error) + // WriteRepositoryExists returns whether a repository is configured for the given URL with write credentials + WriteRepositoryExists(ctx context.Context, repoURL, project string) (bool, error) + // UpdateWriteRepository updates a repository with write credentials + UpdateWriteRepository(ctx context.Context, r *appv1.Repository) (*appv1.Repository, error) + // DeleteWriteRepository deletes a repository from config with write credentials + DeleteWriteRepository(ctx context.Context, name, project string) error + // ListRepositoryCredentials list all repo credential sets URL patterns ListRepositoryCredentials(ctx context.Context) ([]string, error) // GetRepositoryCredentials gets repo credentials for given URL @@ -72,6 +87,17 @@ type ArgoDB interface { // DeleteRepositoryCredentials deletes a repository credential set from config DeleteRepositoryCredentials(ctx context.Context, name string) error + // ListWriteRepositoryCredentials list all repo write credential sets URL patterns + ListWriteRepositoryCredentials(ctx context.Context) ([]string, error) + // GetWriteRepositoryCredentials gets repo write credentials for given URL + GetWriteRepositoryCredentials(ctx context.Context, name string) (*appv1.RepoCreds, error) + // CreateWriteRepositoryCredentials creates a repository write credential set + CreateWriteRepositoryCredentials(ctx context.Context, r *appv1.RepoCreds) (*appv1.RepoCreds, error) + // UpdateWriteRepositoryCredentials updates a repository write credential set + UpdateWriteRepositoryCredentials(ctx context.Context, r *appv1.RepoCreds) (*appv1.RepoCreds, error) + // DeleteWriteRepositoryCredentials deletes a repository write credential set from config + DeleteWriteRepositoryCredentials(ctx context.Context, name string) error + // ListRepoCertificates lists all configured certificates ListRepoCertificates(ctx context.Context, selector *CertificateListSelector) (*appv1.RepositoryCertificateList, error) // CreateRepoCertificate creates a new certificate entry @@ -81,6 +107,9 @@ type ArgoDB interface { // GetAllHelmRepositoryCredentials gets all repo credentials GetAllHelmRepositoryCredentials(ctx context.Context) ([]*appv1.RepoCreds, error) + // GetWriteCredentials gets repo credentials specific to the hydrator for given URL + GetWriteCredentials(ctx context.Context, repoURL string) (*appv1.Repository, error) + // ListHelmRepositories lists repositories ListHelmRepositories(ctx context.Context) ([]*appv1.Repository, error) diff --git a/util/db/db_test.go b/util/db/db_test.go index 38d56a4bceac1..8227f86964bcc 100644 --- a/util/db/db_test.go +++ b/util/db/db_test.go @@ -47,7 +47,7 @@ func getClientset(config map[string]string, objects ...runtime.Object) *fake.Cli }, Data: config, } - return fake.NewSimpleClientset(append(objects, &cm, &secret)...) + return fake.NewClientset(append(objects, &cm, &secret)...) } func TestCreateRepository(t *testing.T) { @@ -628,13 +628,13 @@ func TestFuzzyEquivalence(t *testing.T) { repo, err = db.CreateRepository(ctx, &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-apps.git", }) - assert.Contains(t, err.Error(), "already exists") + require.ErrorContains(t, err, "already exists") assert.Nil(t, repo) repo, err = db.CreateRepository(ctx, &v1alpha1.Repository{ Repo: "https://github.com/argoproj/argocd-example-APPS", }) - assert.Contains(t, err.Error(), "already exists") + require.ErrorContains(t, err, "already exists") assert.Nil(t, repo) repo, err = db.GetRepository(ctx, "https://github.com/argoproj/argocd-example-APPS", "") diff --git a/util/db/gpgkeys_test.go b/util/db/gpgkeys_test.go index dfc0d8fdaf99b..731293b5b279b 100644 --- a/util/db/gpgkeys_test.go +++ b/util/db/gpgkeys_test.go @@ -112,7 +112,7 @@ func getGPGKeysClientset(gpgCM v1.ConfigMap) *fake.Clientset { Data: nil, } - return fake.NewSimpleClientset([]runtime.Object{&cm, &gpgCM}...) + return fake.NewClientset([]runtime.Object{&cm, &gpgCM}...) } func Test_ValidatePGPKey(t *testing.T) { diff --git a/util/db/helmrepository.go b/util/db/helmrepository.go index 13118462e51b6..0cc6bb2742572 100644 --- a/util/db/helmrepository.go +++ b/util/db/helmrepository.go @@ -59,7 +59,7 @@ func (db *db) ListHelmRepositories(ctx context.Context) ([]*v1alpha1.Repository, } result[i] = repo } - repos, err := db.listRepositories(ctx, ptr.To("helm")) + repos, err := db.listRepositories(ctx, ptr.To("helm"), false) if err != nil { return nil, fmt.Errorf("failed to list Helm repositories: %w", err) } diff --git a/util/db/mocks/ArgoDB.go b/util/db/mocks/ArgoDB.go index 928cb0292eab7..562d07ed595d9 100644 --- a/util/db/mocks/ArgoDB.go +++ b/util/db/mocks/ArgoDB.go @@ -175,6 +175,66 @@ func (_m *ArgoDB) CreateRepositoryCredentials(ctx context.Context, r *v1alpha1.R return r0, r1 } +// CreateWriteRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateWriteRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) CreateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for CreateWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // DeleteCluster provides a mock function with given fields: ctx, server func (_m *ArgoDB) DeleteCluster(ctx context.Context, server string) error { ret := _m.Called(ctx, server) @@ -247,6 +307,42 @@ func (_m *ArgoDB) DeleteRepositoryCredentials(ctx context.Context, name string) return r0 } +// DeleteWriteRepository provides a mock function with given fields: ctx, name, project +func (_m *ArgoDB) DeleteWriteRepository(ctx context.Context, name string, project string) error { + ret := _m.Called(ctx, name, project) + + if len(ret) == 0 { + panic("no return value specified for DeleteWriteRepository") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { + r0 = rf(ctx, name, project) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteWriteRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) DeleteWriteRepositoryCredentials(ctx context.Context, name string) error { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for DeleteWriteRepositoryCredentials") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, name) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetAllHelmRepositoryCredentials provides a mock function with given fields: ctx func (_m *ArgoDB) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*v1alpha1.RepoCreds, error) { ret := _m.Called(ctx) @@ -415,6 +511,36 @@ func (_m *ArgoDB) GetProjectRepositories(ctx context.Context, project string) ([ return r0, r1 } +// GetProjectWriteRepositories provides a mock function with given fields: ctx, project +func (_m *ArgoDB) GetProjectWriteRepositories(ctx context.Context, project string) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx, project) + + if len(ret) == 0 { + panic("no return value specified for GetProjectWriteRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string) []*v1alpha1.Repository); ok { + r0 = rf(ctx, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetRepository provides a mock function with given fields: ctx, url, project func (_m *ArgoDB) GetRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { ret := _m.Called(ctx, url, project) @@ -475,6 +601,96 @@ func (_m *ArgoDB) GetRepositoryCredentials(ctx context.Context, name string) (*v return r0, r1 } +// GetWriteCredentials provides a mock function with given fields: ctx, repoURL +func (_m *ArgoDB) GetWriteCredentials(ctx context.Context, repoURL string) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, repoURL) + + if len(ret) == 0 { + panic("no return value specified for GetWriteCredentials") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.Repository, error)); ok { + return rf(ctx, repoURL) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.Repository); ok { + r0 = rf(ctx, repoURL) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, repoURL) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetWriteRepository provides a mock function with given fields: ctx, url, project +func (_m *ArgoDB) GetWriteRepository(ctx context.Context, url string, project string) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, url, project) + + if len(ret) == 0 { + panic("no return value specified for GetWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v1alpha1.Repository, error)); ok { + return rf(ctx, url, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) *v1alpha1.Repository); ok { + r0 = rf(ctx, url, project) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, url, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetWriteRepositoryCredentials provides a mock function with given fields: ctx, name +func (_m *ArgoDB) GetWriteRepositoryCredentials(ctx context.Context, name string) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, name) + + if len(ret) == 0 { + panic("no return value specified for GetWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // ListClusters provides a mock function with given fields: ctx func (_m *ArgoDB) ListClusters(ctx context.Context) (*v1alpha1.ClusterList, error) { ret := _m.Called(ctx) @@ -655,6 +871,66 @@ func (_m *ArgoDB) ListRepositoryCredentials(ctx context.Context) ([]string, erro return r0, r1 } +// ListWriteRepositories provides a mock function with given fields: ctx +func (_m *ArgoDB) ListWriteRepositories(ctx context.Context) ([]*v1alpha1.Repository, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListWriteRepositories") + } + + var r0 []*v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*v1alpha1.Repository, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*v1alpha1.Repository); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListWriteRepositoryCredentials provides a mock function with given fields: ctx +func (_m *ArgoDB) ListWriteRepositoryCredentials(ctx context.Context) ([]string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ListWriteRepositoryCredentials") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // RemoveRepoCertificates provides a mock function with given fields: ctx, selector func (_m *ArgoDB) RemoveRepoCertificates(ctx context.Context, selector *db.CertificateListSelector) (*v1alpha1.RepositoryCertificateList, error) { ret := _m.Called(ctx, selector) @@ -803,6 +1079,66 @@ func (_m *ArgoDB) UpdateRepositoryCredentials(ctx context.Context, r *v1alpha1.R return r0, r1 } +// UpdateWriteRepository provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateWriteRepository(ctx context.Context, r *v1alpha1.Repository) (*v1alpha1.Repository, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateWriteRepository") + } + + var r0 *v1alpha1.Repository + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) (*v1alpha1.Repository, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.Repository) *v1alpha1.Repository); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.Repository) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.Repository) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateWriteRepositoryCredentials provides a mock function with given fields: ctx, r +func (_m *ArgoDB) UpdateWriteRepositoryCredentials(ctx context.Context, r *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for UpdateWriteRepositoryCredentials") + } + + var r0 *v1alpha1.RepoCreds + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) (*v1alpha1.RepoCreds, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.RepoCreds) *v1alpha1.RepoCreds); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1alpha1.RepoCreds) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.RepoCreds) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // WatchClusters provides a mock function with given fields: ctx, handleAddEvent, handleModEvent, handleDeleteEvent func (_m *ArgoDB) WatchClusters(ctx context.Context, handleAddEvent func(*v1alpha1.Cluster), handleModEvent func(*v1alpha1.Cluster, *v1alpha1.Cluster), handleDeleteEvent func(string)) error { ret := _m.Called(ctx, handleAddEvent, handleModEvent, handleDeleteEvent) @@ -821,6 +1157,34 @@ func (_m *ArgoDB) WatchClusters(ctx context.Context, handleAddEvent func(*v1alph return r0 } +// WriteRepositoryExists provides a mock function with given fields: ctx, repoURL, project +func (_m *ArgoDB) WriteRepositoryExists(ctx context.Context, repoURL string, project string) (bool, error) { + ret := _m.Called(ctx, repoURL, project) + + if len(ret) == 0 { + panic("no return value specified for WriteRepositoryExists") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (bool, error)); ok { + return rf(ctx, repoURL, project) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) bool); ok { + r0 = rf(ctx, repoURL, project) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, repoURL, project) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewArgoDB creates a new instance of ArgoDB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewArgoDB(t interface { diff --git a/util/db/repository.go b/util/db/repository.go index a186cb07cc31a..f6e7a708d04df 100644 --- a/util/db/repository.go +++ b/util/db/repository.go @@ -5,10 +5,11 @@ import ( "fmt" "hash/fnv" + apiv1 "k8s.io/api/core/v1" + log "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - apiv1 "k8s.io/api/core/v1" appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -77,6 +78,20 @@ func (db *db) CreateRepository(ctx context.Context, r *appsv1.Repository) (*apps return secretBackend.CreateRepository(ctx, r) } +func (db *db) CreateWriteRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + secretBackend := db.repoWriteBackend() + secretExists, err := secretBackend.RepositoryExists(ctx, r.Repo, r.Project, false) + if err != nil { + return nil, err + } + + if secretExists { + return nil, status.Errorf(codes.AlreadyExists, "repository %q already exists", r.Repo) + } + + return secretBackend.CreateRepository(ctx, r) +} + func (db *db) GetRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { repository, err := db.getRepository(ctx, repoURL, project) if err != nil { @@ -90,12 +105,34 @@ func (db *db) GetRepository(ctx context.Context, repoURL, project string) (*apps return repository, err } +func (db *db) GetWriteRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { + repository, err := db.repoWriteBackend().GetRepository(ctx, repoURL, project) + if err != nil { + return repository, fmt.Errorf("unable to get write repository %q: %w", repoURL, err) + } + + // TODO: enrich with write credentials. + //if err := db.enrichCredsToRepo(ctx, repository); err != nil { + // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) + //} + + return repository, err +} + func (db *db) GetProjectRepositories(ctx context.Context, project string) ([]*appsv1.Repository, error) { + return db.getRepositories(settings.ByProjectRepoIndexer, project) +} + +func (db *db) GetProjectWriteRepositories(ctx context.Context, project string) ([]*appsv1.Repository, error) { + return db.getRepositories(settings.ByProjectRepoWriteIndexer, project) +} + +func (db *db) getRepositories(indexer, project string) ([]*appv1.Repository, error) { informer, err := db.settingsMgr.GetSecretsInformer() if err != nil { return nil, err } - secrets, err := informer.GetIndexer().ByIndex(settings.ByProjectRepoIndexer, project) + secrets, err := informer.GetIndexer().ByIndex(indexer, project) if err != nil { return nil, err } @@ -121,6 +158,11 @@ func (db *db) RepositoryExists(ctx context.Context, repoURL, project string) (bo return legacyBackend.RepositoryExists(ctx, repoURL, project, true) } +func (db *db) WriteRepositoryExists(ctx context.Context, repoURL, project string) (bool, error) { + secretsBackend := db.repoWriteBackend() + return secretsBackend.RepositoryExists(ctx, repoURL, project, true) +} + func (db *db) getRepository(ctx context.Context, repoURL, project string) (*appsv1.Repository, error) { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepositoryExists(ctx, repoURL, project, true) @@ -150,24 +192,37 @@ func (db *db) getRepository(ctx context.Context, repoURL, project string) (*apps } func (db *db) ListRepositories(ctx context.Context) ([]*appsv1.Repository, error) { - return db.listRepositories(ctx, nil) + return db.listRepositories(ctx, nil, false) } -func (db *db) listRepositories(ctx context.Context, repoType *string) ([]*appsv1.Repository, error) { +func (db *db) ListWriteRepositories(ctx context.Context) ([]*appsv1.Repository, error) { + return db.listRepositories(ctx, nil, true) +} + +func (db *db) listRepositories(ctx context.Context, repoType *string, writeCreds bool) ([]*appsv1.Repository, error) { // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that // repositories from secrets overlay repositories from legacys. - secretRepositories, err := db.repoBackend().ListRepositories(ctx, repoType) - if err != nil { - return nil, err - } + var repositories []*appv1.Repository + if writeCreds { + var err error + repositories, err = db.repoWriteBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } + } else { + secretRepositories, err := db.repoBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } - legacyRepositories, err := db.legacyRepoBackend().ListRepositories(ctx, repoType) - if err != nil { - return nil, err - } + legacyRepositories, err := db.legacyRepoBackend().ListRepositories(ctx, repoType) + if err != nil { + return nil, err + } - repositories := append(secretRepositories, legacyRepositories...) + repositories = append(secretRepositories, legacyRepositories...) + } if err := db.enrichCredsToRepos(ctx, repositories); err != nil { return nil, err } @@ -196,6 +251,20 @@ func (db *db) UpdateRepository(ctx context.Context, r *appsv1.Repository) (*apps return nil, status.Errorf(codes.NotFound, "repo '%s' not found", r.Repo) } +func (db *db) UpdateWriteRepository(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + secretBackend := db.repoWriteBackend() + exists, err := secretBackend.RepositoryExists(ctx, r.Repo, r.Project, false) + if err != nil { + return nil, err + } + + if !exists { + return nil, status.Errorf(codes.NotFound, "repo '%s' not found", r.Repo) + } + + return secretBackend.UpdateRepository(ctx, r) +} + func (db *db) DeleteRepository(ctx context.Context, repoURL, project string) error { secretsBackend := db.repoBackend() exists, err := secretsBackend.RepositoryExists(ctx, repoURL, project, false) @@ -216,6 +285,20 @@ func (db *db) DeleteRepository(ctx context.Context, repoURL, project string) err return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL) } +func (db *db) DeleteWriteRepository(ctx context.Context, repoURL, project string) error { + secretsBackend := db.repoWriteBackend() + exists, err := secretsBackend.RepositoryExists(ctx, repoURL, project, false) + if err != nil { + return err + } + + if !exists { + return status.Errorf(codes.NotFound, "repo '%s' not found", repoURL) + } + + return secretsBackend.DeleteRepository(ctx, repoURL, project) +} + // ListRepositoryCredentials returns a list of URLs that contain repo credential sets func (db *db) ListRepositoryCredentials(ctx context.Context) ([]string, error) { // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that @@ -234,6 +317,15 @@ func (db *db) ListRepositoryCredentials(ctx context.Context) ([]string, error) { return append(secretRepoCreds, legacyRepoCreds...), nil } +// ListWriteRepositoryCredentials returns a list of URLs that contain repo write credential sets +func (db *db) ListWriteRepositoryCredentials(ctx context.Context) ([]string, error) { + secretRepoCreds, err := db.repoWriteBackend().ListRepoCreds(ctx) + if err != nil { + return nil, err + } + return secretRepoCreds, nil +} + // GetRepositoryCredentials retrieves a repository credential set func (db *db) GetRepositoryCredentials(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { secretsBackend := db.repoBackend() @@ -263,6 +355,31 @@ func (db *db) GetRepositoryCredentials(ctx context.Context, repoURL string) (*ap return nil, nil } +// GetWriteRepositoryCredentials retrieves a repository write credential set +func (db *db) GetWriteRepositoryCredentials(ctx context.Context, repoURL string) (*appsv1.RepoCreds, error) { + secretBackend := db.repoWriteBackend() + exists, err := secretBackend.RepoCredsExists(ctx, repoURL) + if err != nil { + return nil, fmt.Errorf("unable to check if repository write credentials for %q exists from secrets backend: %w", repoURL, err) + } + + if !exists { + return nil, nil + } + + // TODO: enrich with write credentials. + //if err := db.enrichCredsToRepo(ctx, repository); err != nil { + // return repository, fmt.Errorf("unable to enrich write repository %q info with credentials: %w", repoURL, err) + //} + + creds, err := secretBackend.GetRepoCreds(ctx, repoURL) + if err != nil { + return nil, fmt.Errorf("unable to get repository write credentials for %q from secrets backend: %w", repoURL, err) + } + + return creds, nil +} + // GetAllHelmRepositoryCredentials retrieves all repository credentials func (db *db) GetAllHelmRepositoryCredentials(ctx context.Context) ([]*appsv1.RepoCreds, error) { // TODO It would be nice to check for duplicates between secret and legacy repositories and make it so that @@ -302,6 +419,21 @@ func (db *db) CreateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCre return secretBackend.CreateRepoCreds(ctx, r) } +// CreateWriteRepositoryCredentials creates a repository write credential set +func (db *db) CreateWriteRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { + secretBackend := db.repoWriteBackend() + secretExists, err := secretBackend.RepoCredsExists(ctx, r.URL) + if err != nil { + return nil, err + } + + if secretExists { + return nil, status.Errorf(codes.AlreadyExists, "write repository credentials %q already exists", r.URL) + } + + return secretBackend.CreateRepoCreds(ctx, r) +} + // UpdateRepositoryCredentials updates a repository credential set func (db *db) UpdateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { secretsBackend := db.repoBackend() @@ -323,6 +455,21 @@ func (db *db) UpdateRepositoryCredentials(ctx context.Context, r *appsv1.RepoCre return nil, status.Errorf(codes.NotFound, "repository credentials '%s' not found", r.URL) } +// UpdateWriteRepositoryCredentials updates a repository write credential set +func (db *db) UpdateWriteRepositoryCredentials(ctx context.Context, r *appsv1.RepoCreds) (*appsv1.RepoCreds, error) { + secretBackend := db.repoWriteBackend() + exists, err := secretBackend.RepoCredsExists(ctx, r.URL) + if err != nil { + return nil, err + } + + if !exists { + return nil, status.Errorf(codes.NotFound, "write repository credentials '%s' not found", r.URL) + } + + return secretBackend.UpdateRepoCreds(ctx, r) +} + // DeleteRepositoryCredentials deletes a repository credential set from config, and // also all the secrets which actually contained the credentials. func (db *db) DeleteRepositoryCredentials(ctx context.Context, name string) error { @@ -345,6 +492,19 @@ func (db *db) DeleteRepositoryCredentials(ctx context.Context, name string) erro return status.Errorf(codes.NotFound, "repository credentials '%s' not found", name) } +// DeleteWriteRepositoryCredentials deletes a repository write credential set from config, and +// also all the secrets which actually contained the credentials. +func (db *db) DeleteWriteRepositoryCredentials(ctx context.Context, name string) error { + secretBackend := db.repoWriteBackend() + exists, err := secretBackend.RepoCredsExists(ctx, name) + if err != nil { + return err + } else if exists { + return secretBackend.DeleteRepoCreds(ctx, name) + } + return status.Errorf(codes.NotFound, "write repository credentials '%s' not found", name) +} + func (db *db) enrichCredsToRepos(ctx context.Context, repositories []*appsv1.Repository) error { for _, repository := range repositories { if err := db.enrichCredsToRepo(ctx, repository); err != nil { @@ -358,6 +518,10 @@ func (db *db) repoBackend() repositoryBackend { return &secretsRepositoryBackend{db: db} } +func (db *db) repoWriteBackend() repositoryBackend { + return &secretsRepositoryBackend{db: db, writeCreds: true} +} + func (db *db) legacyRepoBackend() repositoryBackend { return &legacyRepositoryBackend{db: db} } diff --git a/util/db/repository_secrets.go b/util/db/repository_secrets.go index c4ed8396764bb..1897e54d6dcf3 100644 --- a/util/db/repository_secrets.go +++ b/util/db/repository_secrets.go @@ -21,6 +21,8 @@ var _ repositoryBackend = &secretsRepositoryBackend{} type secretsRepositoryBackend struct { db *db + // If true, the backend will manage write only credentials. If false, it will manage only read credentials. + writeCreds bool } func (s *secretsRepositoryBackend) CreateRepository(ctx context.Context, repository *appsv1.Repository) (*appsv1.Repository, error) { @@ -32,7 +34,7 @@ func (s *secretsRepositoryBackend) CreateRepository(ctx context.Context, reposit }, } - repositoryToSecret(repository, repositorySecret) + s.repositoryToSecret(repository, repositorySecret) _, err := s.db.createSecret(ctx, repositorySecret) if err != nil { @@ -102,7 +104,7 @@ func (s *secretsRepositoryBackend) GetRepository(ctx context.Context, repoURL, p func (s *secretsRepositoryBackend) ListRepositories(ctx context.Context, repoType *string) ([]*appsv1.Repository, error) { var repos []*appsv1.Repository - secrets, err := s.db.listSecretsByType(common.LabelValueSecretTypeRepository) + secrets, err := s.db.listSecretsByType(s.getSecretType()) if err != nil { return nil, err } @@ -141,7 +143,7 @@ func (s *secretsRepositoryBackend) UpdateRepository(ctx context.Context, reposit return nil, err } - repositoryToSecret(repository, repositorySecret) + s.repositoryToSecret(repository, repositorySecret) _, err = s.db.kubeclientset.CoreV1().Secrets(s.db.ns).Update(ctx, repositorySecret, metav1.UpdateOptions{}) if err != nil { @@ -362,7 +364,7 @@ func secretToRepository(secret *corev1.Secret) (*appsv1.Repository, error) { return repository, nil } -func repositoryToSecret(repository *appsv1.Repository, secret *corev1.Secret) { +func (s *secretsRepositoryBackend) repositoryToSecret(repository *appsv1.Repository, secret *corev1.Secret) { if secret.Data == nil { secret.Data = make(map[string][]byte) } @@ -388,7 +390,7 @@ func repositoryToSecret(repository *appsv1.Repository, secret *corev1.Secret) { updateSecretString(secret, "noProxy", repository.NoProxy) updateSecretString(secret, "gcpServiceAccountKey", repository.GCPServiceAccountKey) updateSecretBool(secret, "forceHttpBasicAuth", repository.ForceHttpBasicAuth) - addSecretMetadata(secret, common.LabelValueSecretTypeRepository) + addSecretMetadata(secret, s.getSecretType()) } func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*appsv1.RepoCreds, error) { @@ -459,7 +461,7 @@ func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) { } func (s *secretsRepositoryBackend) getRepositorySecret(repoURL, project string, allowFallback bool) (*corev1.Secret, error) { - secrets, err := s.db.listSecretsByType(common.LabelValueSecretTypeRepository) + secrets, err := s.db.listSecretsByType(s.getSecretType()) if err != nil { return nil, fmt.Errorf("failed to list repository secrets: %w", err) } @@ -524,3 +526,10 @@ func (s *secretsRepositoryBackend) getRepositoryCredentialIndex(repoCredentials } return idx } + +func (s *secretsRepositoryBackend) getSecretType() string { + if s.writeCreds { + return common.LabelValueSecretTypeRepositoryWrite + } + return common.LabelValueSecretTypeRepository +} diff --git a/util/db/repository_secrets_test.go b/util/db/repository_secrets_test.go index 0a74a9806f5cb..e484999f884e7 100644 --- a/util/db/repository_secrets_test.go +++ b/util/db/repository_secrets_test.go @@ -83,7 +83,8 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { // given t.Parallel() secret := &corev1.Secret{} - repositoryToSecret(repo, secret) + s := secretsRepositoryBackend{} + s.repositoryToSecret(repo, secret) delete(secret.Labels, common.LabelKeySecretType) f := setupWithK8sObjects(secret) f.clientSet.ReactionChain = nil @@ -119,7 +120,8 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) { Namespace: "default", }, } - repositoryToSecret(repo, secret) + s := secretsRepositoryBackend{} + s.repositoryToSecret(repo, secret) f := setupWithK8sObjects(secret) f.clientSet.ReactionChain = nil f.clientSet.WatchReactionChain = nil @@ -682,7 +684,7 @@ func TestSecretsRepositoryBackend_GetRepoCreds(t *testing.T) { repoCred, err := testee.GetRepoCreds(context.TODO(), "git@github.com:argoproj") require.NoError(t, err) - assert.NotNil(t, repoCred) + require.NotNil(t, repoCred) assert.Equal(t, "git@github.com:argoproj", repoCred.URL) assert.Equal(t, "someUsername", repoCred.Username) assert.Equal(t, "somePassword", repoCred.Password) diff --git a/util/db/secrets.go b/util/db/secrets.go index 021cf899c0e17..38136d8c43dba 100644 --- a/util/db/secrets.go +++ b/util/db/secrets.go @@ -20,6 +20,7 @@ import ( "k8s.io/client-go/tools/cache" "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/util" ) func (db *db) listSecretsByType(types ...string) ([]*apiv1.Secret, error) { @@ -38,6 +39,10 @@ func (db *db) listSecretsByType(types ...string) ([]*apiv1.Secret, error) { if err != nil { return nil, err } + // SecretNamespaceLister lists all Secrets in the indexer for a given namespace. + // Objects returned by the lister must be treated as read-only. + // To allow us to modify the secrets, make a copy + secrets = util.SecretCopy(secrets) return secrets, nil } diff --git a/util/db/write_repository.go b/util/db/write_repository.go new file mode 100644 index 0000000000000..0afd57cd5bdb9 --- /dev/null +++ b/util/db/write_repository.go @@ -0,0 +1,43 @@ +package db + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + corev1 "k8s.io/api/core/v1" + + "github.com/argoproj/argo-cd/v2/common" + appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func (db *db) GetWriteCredentials(ctx context.Context, repoURL string) (*appsv1.Repository, error) { + secret, err := db.getRepoCredsSecret(repoURL) + if err != nil { + if status.Code(err) == codes.NotFound { + return nil, nil + } + + return nil, fmt.Errorf("failed to get repository-write credentials Secret: %w", err) + } + + return secretToRepository(secret) +} + +func (db *db) getRepoCredsSecret(repoURL string) (*corev1.Secret, error) { + // Should reuse stuff from repo secrets backend... + secretBackend := &secretsRepositoryBackend{db: db} + + secrets, err := db.listSecretsByType(common.LabelValueSecretTypeRepositoryWrite) + if err != nil { + return nil, fmt.Errorf("failed to list repository-write credentials Secrets: %w", err) + } + + index := secretBackend.getRepositoryCredentialIndex(secrets, repoURL) + if index < 0 { + return nil, status.Errorf(codes.NotFound, "repository-write credentials %q not found", repoURL) + } + + return secrets[index], nil +} diff --git a/util/env/env.go b/util/env/env.go index e9c2ff41d393e..686ef8089154c 100644 --- a/util/env/env.go +++ b/util/env/env.go @@ -7,8 +7,6 @@ import ( "strings" "time" - timeutil "github.com/argoproj/pkg/time" - log "github.com/sirupsen/logrus" ) @@ -133,13 +131,12 @@ func ParseDurationFromEnv(env string, defaultValue, min, max time.Duration) time if str == "" { return defaultValue } - durPtr, err := timeutil.ParseDuration(str) + dur, err := time.ParseDuration(str) if err != nil { log.Warnf("Could not parse '%s' as a duration string from environment %s", str, env) return defaultValue } - dur := *durPtr if dur < min { log.Warnf("Value in %s is %s, which is less than minimum %s allowed", env, dur, min) return defaultValue diff --git a/util/env/env_test.go b/util/env/env_test.go index 84e87052c9e33..48da08b0668f2 100644 --- a/util/env/env_test.go +++ b/util/env/env_test.go @@ -3,6 +3,7 @@ package env import ( "fmt" "math" + "strconv" "testing" "time" @@ -23,10 +24,10 @@ func TestParseNumFromEnv(t *testing.T) { {"Valid positive number", "200", 200}, {"Valid negative number", "-200", -200}, {"Invalid number", "abc", def}, - {"Equals minimum", fmt.Sprintf("%d", math.MinInt+1), min}, - {"Equals maximum", fmt.Sprintf("%d", math.MaxInt-1), max}, - {"Less than minimum", fmt.Sprintf("%d", math.MinInt), def}, - {"Greater than maximum", fmt.Sprintf("%d", math.MaxInt), def}, + {"Equals minimum", strconv.Itoa(math.MinInt + 1), min}, + {"Equals maximum", strconv.Itoa(math.MaxInt - 1), max}, + {"Less than minimum", strconv.Itoa(math.MinInt), def}, + {"Greater than maximum", strconv.Itoa(math.MaxInt), def}, {"Variable not set", "", def}, } @@ -81,10 +82,10 @@ func TestParseInt64FromEnv(t *testing.T) { }{ {"Valid int64", "200", 200}, {"Text as invalid int64", "abc", def}, - {"Equals maximum", fmt.Sprintf("%d", max), max}, - {"Equals minimum", fmt.Sprintf("%d", min), min}, - {"Greater than maximum", fmt.Sprintf("%d", max+1), def}, - {"Less than minimum", fmt.Sprintf("%d", min-1), def}, + {"Equals maximum", strconv.FormatInt(max, 10), max}, + {"Equals minimum", strconv.FormatInt(min, 10), min}, + {"Greater than maximum", strconv.FormatInt(max+1, 10), def}, + {"Less than minimum", strconv.FormatInt(min-1, 10), def}, {"Environment not set", "", def}, } @@ -114,6 +115,10 @@ func TestParseDurationFromEnv(t *testing.T) { name: "ValidValueSet", env: "2s", expected: time.Second * 2, + }, { + name: "ValidValueSetMs", + env: "2500ms", + expected: time.Millisecond * 2500, }, { name: "MoreThanMaxSet", env: "6s", diff --git a/util/exec/exec.go b/util/exec/exec.go index 493d8855c8c80..17eab41a20445 100644 --- a/util/exec/exec.go +++ b/util/exec/exec.go @@ -52,7 +52,7 @@ func RunWithRedactor(cmd *exec.Cmd, redactor func(text string) string) (string, func RunWithExecRunOpts(cmd *exec.Cmd, opts ExecRunOpts) (string, error) { cmdOpts := argoexec.CmdOpts{Timeout: timeout, Redactor: opts.Redactor, TimeoutBehavior: opts.TimeoutBehavior, SkipErrorLogging: opts.SkipErrorLogging} span := tracing.NewLoggingTracer(log.NewLogrusLogger(log.NewWithCurrentConfig())).StartSpan(fmt.Sprintf("exec %v", cmd.Args[0])) - span.SetBaggageItem("dir", fmt.Sprintf("%v", cmd.Dir)) + span.SetBaggageItem("dir", cmd.Dir) if cmdOpts.Redactor != nil { span.SetBaggageItem("args", opts.Redactor(fmt.Sprintf("%v", cmd.Args))) } else { diff --git a/util/exec/exec_test.go b/util/exec/exec_test.go index a3ae4888f2cf4..c41ee100f55ad 100644 --- a/util/exec/exec_test.go +++ b/util/exec/exec_test.go @@ -32,13 +32,13 @@ func TestRun(t *testing.T) { func TestHideUsernamePassword(t *testing.T) { _, err := RunWithRedactor(exec.Command("helm registry login https://charts.bitnami.com/bitnami", "--username", "foo", "--password", "bar"), nil) - assert.NotEmpty(t, err) + require.Error(t, err) redactor := func(text string) string { return regexp.MustCompile("(--username|--password) [^ ]*").ReplaceAllString(text, "$1 ******") } _, err = RunWithRedactor(exec.Command("helm registry login https://charts.bitnami.com/bitnami", "--username", "foo", "--password", "bar"), redactor) - assert.NotEmpty(t, err) + require.Error(t, err) } func TestRunWithExecRunOpts(t *testing.T) { @@ -52,7 +52,7 @@ func TestRunWithExecRunOpts(t *testing.T) { }, } _, err := RunWithExecRunOpts(exec.Command("sh", "-c", "trap 'trap - 15 && echo captured && exit' 15 && sleep 2"), opts) - assert.Contains(t, err.Error(), "failed timeout after 200ms") + assert.ErrorContains(t, err, "failed timeout after 200ms") } func Test_getCommandArgsToLog(t *testing.T) { diff --git a/util/git/client.go b/util/git/client.go index 3b9c6d42450a5..0b9ab11b79eee 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -69,7 +69,7 @@ type Client interface { Init() error Fetch(revision string) error Submodule() error - Checkout(revision string, submoduleEnabled bool) error + Checkout(revision string, submoduleEnabled bool) (string, error) LsRefs() (*Refs, error) LsRemote(revision string) (string, error) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) @@ -80,11 +80,23 @@ type Client interface { IsAnnotatedTag(string) bool ChangedFiles(revision string, targetRevision string) ([]string, error) IsRevisionPresent(revision string) bool + // SetAuthor sets the author name and email in the git configuration. + SetAuthor(name, email string) (string, error) + // CheckoutOrOrphan checks out the branch. If the branch does not exist, it creates an orphan branch. + CheckoutOrOrphan(branch string, submoduleEnabled bool) (string, error) + // CheckoutOrNew checks out the given branch. If the branch does not exist, it creates an empty branch based on + // the base branch. + CheckoutOrNew(branch, base string, submoduleEnabled bool) (string, error) + // RemoveContents removes all files from the git repository. + RemoveContents() (string, error) + // CommitAndPush commits and pushes changes to the target branch. + CommitAndPush(branch, message string) (string, error) } type EventHandlers struct { OnLsRemote func(repo string) func() OnFetch func(repo string) func() + OnPush func(repo string) func() } // nativeGitClient implements Client interface using git CLI @@ -459,43 +471,43 @@ func (m *nativeGitClient) Submodule() error { return nil } -// Checkout checkout specified revision -func (m *nativeGitClient) Checkout(revision string, submoduleEnabled bool) error { +// Checkout checks out the specified revision +func (m *nativeGitClient) Checkout(revision string, submoduleEnabled bool) (string, error) { if revision == "" || revision == "HEAD" { revision = "origin/HEAD" } - if _, err := m.runCmd("checkout", "--force", revision); err != nil { - return err + if out, err := m.runCmd("checkout", "--force", revision); err != nil { + return out, fmt.Errorf("failed to checkout %s: %w", revision, err) } // We must populate LFS content by using lfs checkout, if we have at least // one LFS reference in the current revision. if m.IsLFSEnabled() { if largeFiles, err := m.LsLargeFiles(); err == nil { if len(largeFiles) > 0 { - if _, err := m.runCmd("lfs", "checkout"); err != nil { - return err + if out, err := m.runCmd("lfs", "checkout"); err != nil { + return out, fmt.Errorf("failed to checkout LFS files: %w", err) } } } else { - return err + return "", fmt.Errorf("failed to list LFS files: %w", err) } } if _, err := os.Stat(m.root + "/.gitmodules"); !os.IsNotExist(err) { if submoduleEnabled { if err := m.Submodule(); err != nil { - return err + return "", fmt.Errorf("failed to update submodules: %w", err) } } } // NOTE // The double “f” in the arguments is not a typo: the first “f” tells // `git clean` to delete untracked files and directories, and the second “f” - // tells it to clean untractked nested Git repositories (for example a + // tells it to clean untracked nested Git repositories (for example a // submodule which has since been removed). - if _, err := m.runCmd("clean", "-ffdx"); err != nil { - return err + if out, err := m.runCmd("clean", "-ffdx"); err != nil { + return out, fmt.Errorf("failed to clean: %w", err) } - return nil + return "", nil } func (m *nativeGitClient) getRefs() ([]*plumbing.Reference, error) { @@ -624,21 +636,16 @@ func (m *nativeGitClient) lsRemote(revision string) (string, error) { refs, err := m.getRefs() if err != nil { - return "", err + return "", fmt.Errorf("failed to list refs: %w", err) } if revision == "" { revision = "HEAD" } - // Check if the revision is a valid semver constraint before attempting to resolve it - if constraint, err := semver.NewConstraint(revision); err == nil { - semverSha := m.resolveSemverRevision(constraint, refs) - if semverSha != "" { - return semverSha, nil - } - } else { - log.Debugf("Revision '%s' is not a valid semver constraint, skipping semver resolution.", revision) + semverSha := m.resolveSemverRevision(revision, refs) + if semverSha != "" { + return semverSha, nil } // refToHash keeps a maps of remote refs to their hash @@ -684,18 +691,31 @@ func (m *nativeGitClient) lsRemote(revision string) (string, error) { // If we get here, revision string had non hexadecimal characters (indicating its a branch, tag, // or symbolic ref) and we were unable to resolve it to a commit SHA. - return "", fmt.Errorf("Unable to resolve '%s' to a commit SHA", revision) + return "", fmt.Errorf("unable to resolve '%s' to a commit SHA", revision) } // resolveSemverRevision is a part of the lsRemote method workflow. -// When the user configure correctly the Git repository revision and the revision is a valid semver constraint -// only the for loop in this function will run, otherwise the lsRemote loop will try to resolve the revision. -// Some examples to illustrate the actual behavior, if: -// * The revision is "v0.1.*"/"0.1.*" or "v0.1.2"/"0.1.2" and there's a tag matching that constraint only this function loop will run; -// * The revision is "v0.1.*"/"0.1.*" or "0.1.2"/"0.1.2" and there is no tag matching that constraint this function loop and lsRemote loop will run for backward compatibility; -// * The revision is "custom-tag" only the lsRemote loop will run because that revision is an invalid semver; -// * The revision is "master-branch" only the lsRemote loop will run because that revision is an invalid semver; -func (m *nativeGitClient) resolveSemverRevision(constraint *semver.Constraints, refs []*plumbing.Reference) string { +// When the user correctly configures the Git repository revision, and that revision is a valid semver constraint, we +// use this logic path rather than the standard lsRemote revision resolution loop. +// Some examples to illustrate the actual behavior - if the revision is: +// * "v0.1.2"/"0.1.2" or "v0.1"/"0.1", then this is not a constraint, it's a pinned version - so we fall back to the standard tag matching in the lsRemote loop. +// * "v0.1.*"/"0.1.*", and there's a tag matching that constraint, then we find the latest matching version and return its commit hash. +// * "v0.1.*"/"0.1.*", and there is *no* tag matching that constraint, then we fall back to the standard tag matching in the lsRemote loop. +// * "custom-tag", only the lsRemote loop will run - because that revision is an invalid semver; +// * "master-branch", only the lsRemote loop will run because that revision is an invalid semver; +func (m *nativeGitClient) resolveSemverRevision(revision string, refs []*plumbing.Reference) string { + if _, err := semver.NewVersion(revision); err == nil { + // If the revision is a valid version, then we know it isn't a constraint; it's just a pin. + // In which case, we should use standard tag resolution mechanisms. + return "" + } + + constraint, err := semver.NewConstraint(revision) + if err != nil { + log.Debugf("Revision '%s' is not a valid semver constraint, skipping semver resolution.", revision) + return "" + } + maxVersion := semver.New(0, 0, 0, "", "") maxVersionHash := plumbing.ZeroHash for _, ref := range refs { @@ -723,6 +743,7 @@ func (m *nativeGitClient) resolveSemverRevision(constraint *semver.Constraints, return "" } + log.Debugf("Semver constraint '%s' resolved to tag '%s', at reference '%s'", revision, maxVersion.Original(), maxVersionHash.String()) return maxVersionHash.String() } @@ -737,11 +758,11 @@ func (m *nativeGitClient) CommitSHA() (string, error) { // returns the meta-data for the commit func (m *nativeGitClient) RevisionMetadata(revision string) (*RevisionMetadata, error) { - out, err := m.runCmd("show", "-s", "--format=%an <%ae>|%at|%B", revision) + out, err := m.runCmd("show", "-s", "--format=%an <%ae>%n%at%n%B", revision) if err != nil { return nil, err } - segments := strings.SplitN(out, "|", 3) + segments := strings.SplitN(out, "\n", 3) if len(segments) != 3 { return nil, fmt.Errorf("expected 3 segments, got %v", segments) } @@ -802,6 +823,123 @@ func (m *nativeGitClient) ChangedFiles(revision string, targetRevision string) ( return files, nil } +// config runs a git config command. +func (m *nativeGitClient) config(args ...string) (string, error) { + args = append([]string{"config"}, args...) + out, err := m.runCmd(args...) + if err != nil { + return out, fmt.Errorf("failed to run git config: %w", err) + } + return out, nil +} + +// SetAuthor sets the author name and email in the git configuration. +func (m *nativeGitClient) SetAuthor(name, email string) (string, error) { + if name != "" { + out, err := m.config("--local", "user.name", name) + if err != nil { + return out, err + } + } + if email != "" { + out, err := m.config("--local", "user.email", email) + if err != nil { + return out, err + } + } + return "", nil +} + +// CheckoutOrOrphan checks out the branch. If the branch does not exist, it creates an orphan branch. +func (m *nativeGitClient) CheckoutOrOrphan(branch string, submoduleEnabled bool) (string, error) { + out, err := m.Checkout(branch, submoduleEnabled) + if err != nil { + // If the branch doesn't exist, create it as an orphan branch. + if strings.Contains(err.Error(), "did not match any file(s) known to git") { + out, err = m.runCmd("switch", "--orphan", branch) + if err != nil { + return out, fmt.Errorf("failed to create orphan branch: %w", err) + } + } else { + return out, fmt.Errorf("failed to checkout branch: %w", err) + } + + // Make an empty initial commit. + out, err = m.runCmd("commit", "--allow-empty", "-m", "Initial commit") + if err != nil { + return out, fmt.Errorf("failed to commit initial commit: %w", err) + } + + // Push the commit. + err = m.runCredentialedCmd("push", "origin", branch) + if err != nil { + return "", fmt.Errorf("failed to push to branch: %w", err) + } + } + return "", nil +} + +// CheckoutOrNew checks out the given branch. If the branch does not exist, it creates an empty branch based on +// the base branch. +func (m *nativeGitClient) CheckoutOrNew(branch, base string, submoduleEnabled bool) (string, error) { + out, err := m.Checkout(branch, submoduleEnabled) + if err != nil { + if strings.Contains(err.Error(), "did not match any file(s) known to git") { + // If the branch does not exist, create any empty branch based on the sync branch + // First, checkout the sync branch. + out, err = m.Checkout(base, submoduleEnabled) + if err != nil { + return out, fmt.Errorf("failed to checkout sync branch: %w", err) + } + + out, err = m.runCmd("checkout", "-b", branch) + if err != nil { + return out, fmt.Errorf("failed to create branch: %w", err) + } + } else { + return out, fmt.Errorf("failed to checkout branch: %w", err) + } + } + return "", nil +} + +// RemoveContents removes all files from the git repository. +func (m *nativeGitClient) RemoveContents() (string, error) { + out, err := m.runCmd("rm", "-r", "--ignore-unmatch", ".") + if err != nil { + return out, fmt.Errorf("failed to clear repo contents: %w", err) + } + return "", nil +} + +// CommitAndPush commits and pushes changes to the target branch. +func (m *nativeGitClient) CommitAndPush(branch, message string) (string, error) { + out, err := m.runCmd("add", ".") + if err != nil { + return out, fmt.Errorf("failed to add files: %w", err) + } + + out, err = m.runCmd("commit", "-m", message) + if err != nil { + if strings.Contains(out, "nothing to commit, working tree clean") { + return out, nil + } + return out, fmt.Errorf("failed to commit: %w", err) + } + + if m.OnPush != nil { + done := m.OnPush(m.repoURL) + defer done() + } + + err = m.runCredentialedCmd("push", "origin", branch) + if err != nil { + return "", fmt.Errorf("failed to push: %w", err) + } + + return "", nil +} + // runWrapper runs a custom command with all the semantics of running the Git client func (m *nativeGitClient) runGnuPGWrapper(wrapper string, args ...string) (string, error) { cmd := exec.Command(wrapper, args...) @@ -841,7 +979,7 @@ func (m *nativeGitClient) runCredentialedCmd(args ...string) error { func (m *nativeGitClient) runCmdOutput(cmd *exec.Cmd, ropts runOpts) (string, error) { cmd.Dir = m.root cmd.Env = append(os.Environ(), cmd.Env...) - // Set $HOME to nowhere, so we can be execute Git regardless of any external + // Set $HOME to nowhere, so we can execute Git regardless of any external // authentication keys (e.g. in ~/.ssh) -- this is especially important for // running tests on local machines and/or CircleCI. cmd.Env = append(cmd.Env, "HOME=/dev/null") diff --git a/util/git/client_test.go b/util/git/client_test.go index c2f8061a1c2f0..a335d4a1bd6c8 100644 --- a/util/git/client_test.go +++ b/util/git/client_test.go @@ -6,7 +6,9 @@ import ( "os/exec" "path" "path/filepath" + "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -20,6 +22,13 @@ func runCmd(workingDir string, name string, args ...string) error { return cmd.Run() } +func outputCmd(workingDir string, name string, args ...string) ([]byte, error) { + cmd := exec.Command(name, args...) + cmd.Dir = workingDir + cmd.Stderr = os.Stderr + return cmd.Output() +} + func _createEmptyGitRepo() (string, error) { tempDir, err := os.MkdirTemp("", "") if err != nil { @@ -173,6 +182,148 @@ func Test_ChangedFiles(t *testing.T) { assert.ElementsMatch(t, []string{"README"}, changedFiles) } +func Test_SemverTags(t *testing.T) { + tempDir := t.TempDir() + + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + mapTagRefs := map[string]string{} + for _, tag := range []string{ + "v1.0.0-rc1", + "v1.0.0-rc2", + "v1.0.0", + "v1.0", + "v1.0.1", + "v1.1.0", + "2024-apple", + "2024-banana", + } { + err = runCmd(client.Root(), "git", "commit", "-m", tag+" commit", "--allow-empty") + require.NoError(t, err) + + // Create an rc semver tag + err = runCmd(client.Root(), "git", "tag", tag) + require.NoError(t, err) + + sha, err := client.LsRemote("HEAD") + require.NoError(t, err) + + mapTagRefs[tag] = sha + } + + for _, tc := range []struct { + name string + ref string + expected string + error bool + }{{ + name: "pinned rc version", + ref: "v1.0.0-rc1", + expected: mapTagRefs["v1.0.0-rc1"], + }, { + name: "lt rc constraint", + ref: "< v1.0.0-rc3", + expected: mapTagRefs["v1.0.0-rc2"], + }, { + name: "pinned major version", + ref: "v1.0.0", + expected: mapTagRefs["v1.0.0"], + }, { + name: "pinned patch version", + ref: "v1.0.1", + expected: mapTagRefs["v1.0.1"], + }, { + name: "pinned minor version", + ref: "v1.1.0", + expected: mapTagRefs["v1.1.0"], + }, { + name: "patch wildcard constraint", + ref: "v1.0.*", + expected: mapTagRefs["v1.0.1"], + }, { + name: "patch tilde constraint", + ref: "~v1.0.0", + expected: mapTagRefs["v1.0.1"], + }, { + name: "minor wildcard constraint", + ref: "v1.*", + expected: mapTagRefs["v1.1.0"], + }, { + // The semver library allows for using both * and x as the wildcard modifier. + name: "alternative minor wildcard constraint", + ref: "v1.x", + expected: mapTagRefs["v1.1.0"], + }, { + name: "minor gte constraint", + ref: ">= v1.0.0", + expected: mapTagRefs["v1.1.0"], + }, { + name: "multiple constraints", + ref: "> v1.0.0 < v1.1.0", + expected: mapTagRefs["v1.0.1"], + }, { + // We treat non-specific semver versions as regular tags, rather than constraints. + name: "non-specific version", + ref: "v1.0", + expected: mapTagRefs["v1.0"], + }, { + // Which means a missing tag will raise an error. + name: "missing non-specific version", + ref: "v1.1", + error: true, + }, { + // This is NOT a semver constraint, so it should always resolve to itself - because specifying a tag should + // return the commit for that tag. + // semver/v3 has the unfortunate semver-ish behaviour where any tag starting with a number is considered to be + // "semver-ish", where that number is the semver major version, and the rest then gets coerced into a beta + // version string. This can cause unexpected behaviour with constraints logic. + // In this case, if the tag is being incorrectly coerced into semver (for being semver-ish), it will incorrectly + // return the commit for the 2024-banana tag; which we want to avoid. + name: "apple non-semver tag", + ref: "2024-apple", + expected: mapTagRefs["2024-apple"], + }, { + name: "banana non-semver tag", + ref: "2024-banana", + expected: mapTagRefs["2024-banana"], + }, { + // A semver version (without constraints) should ONLY match itself. + // We do not want "2024-apple" to get "semver-ish'ed" into matching "2024.0.0-apple"; they're different tags. + name: "no semver tag coercion", + ref: "2024.0.0-apple", + error: true, + }, { + // No minor versions are specified, so we would expect a major version of 2025 or more. + // This is because if we specify > 11 in semver, we would not expect 11.1.0 to pass; it should be 12.0.0 or more. + // Similarly, if we were to specify > 11.0, we would expect 11.1.0 or more. + name: "semver constraints on non-semver tags", + ref: "> 2024-apple", + error: true, + }, { + // However, if one specifies the minor/patch versions, semver constraints can be used to match non-semver tags. + // 2024-banana is considered as "2024.0.0-banana" in semver-ish, and banana > apple, so it's a match. + // Note: this is more for documentation and future reference than real testing, as it seems like quite odd behaviour. + name: "semver constraints on non-semver tags", + ref: "> 2024.0.0-apple", + expected: mapTagRefs["2024-banana"], + }} { + t.Run(tc.name, func(t *testing.T) { + commitSHA, err := client.LsRemote(tc.ref) + if tc.error { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.True(t, IsCommitSHA(commitSHA)) + assert.Equal(t, tc.expected, commitSHA) + }) + } +} + func Test_nativeGitClient_Submodule(t *testing.T) { tempDir, err := os.MkdirTemp("", "") require.NoError(t, err) @@ -222,7 +373,7 @@ func Test_nativeGitClient_Submodule(t *testing.T) { require.NoError(t, err) // Call Checkout() with submoduleEnabled=false. - err = client.Checkout(commitSHA, false) + _, err = client.Checkout(commitSHA, false) require.NoError(t, err) // Check if submodule url does not exist in .git/config @@ -230,7 +381,7 @@ func Test_nativeGitClient_Submodule(t *testing.T) { require.Error(t, err) // Call Submodule() via Checkout() with submoduleEnabled=true. - err = client.Checkout(commitSHA, true) + _, err = client.Checkout(commitSHA, true) require.NoError(t, err) // Check if the .gitmodule URL is reflected in .git/config @@ -296,3 +447,393 @@ func Test_IsRevisionPresent(t *testing.T) { revisionPresent = client.IsRevisionPresent("invalid-revision") assert.False(t, revisionPresent) } + +func Test_nativeGitClient_RevisionMetadata(t *testing.T) { + tempDir := t.TempDir() + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + p := path.Join(client.Root(), "README") + f, err := os.Create(p) + require.NoError(t, err) + _, err = f.WriteString("Hello.") + require.NoError(t, err) + err = f.Close() + require.NoError(t, err) + + err = runCmd(client.Root(), "git", "config", "user.name", "FooBar ||| something\nelse") + require.NoError(t, err) + err = runCmd(client.Root(), "git", "config", "user.email", "foo@foo.com") + require.NoError(t, err) + + err = runCmd(client.Root(), "git", "add", "README") + require.NoError(t, err) + err = runCmd(client.Root(), "git", "commit", "--date=\"Sat Jun 5 20:00:00 2021 +0000 UTC\"", "-m", `| Initial commit | + + +(╯°□°)╯︵ ┻━┻ + `, "-a") + require.NoError(t, err) + + metadata, err := client.RevisionMetadata("HEAD") + require.NoError(t, err) + require.Equal(t, &RevisionMetadata{ + Author: `FooBar ||| somethingelse `, + Date: time.Date(2021, time.June, 5, 20, 0, 0, 0, time.UTC).Local(), + Tags: []string{}, + Message: "| Initial commit |\n\n(╯°□°)╯︵ ┻━┻", + }, metadata) +} + +func Test_nativeGitClient_SetAuthor(t *testing.T) { + expectedName := "Tester" + expectedEmail := "test@example.com" + + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + out, err := client.SetAuthor(expectedName, expectedEmail) + require.NoError(t, err, "error output: ", out) + + // Check git user.name + gitUserName, err := outputCmd(client.Root(), "git", "config", "--local", "user.name") + require.NoError(t, err) + actualName := strings.TrimSpace(string(gitUserName)) + require.Equal(t, expectedName, actualName) + + // Check git user.email + gitUserEmail, err := outputCmd(client.Root(), "git", "config", "--local", "user.email") + require.NoError(t, err) + actualEmail := strings.TrimSpace(string(gitUserEmail)) + require.Equal(t, expectedEmail, actualEmail) +} + +func Test_nativeGitClient_CheckoutOrOrphan(t *testing.T) { + t.Run("checkout to an existing branch", func(t *testing.T) { + // not main or master + expectedBranch := "feature" + + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + // set the author for the initial commit of the orphan branch + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: %s", out) + + // get base branch + gitCurrentBranch, err := outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + baseBranch := strings.TrimSpace(string(gitCurrentBranch)) + + // get base commit + gitCurrentCommitHash, err := outputCmd(tempDir, "git", "rev-parse", "HEAD") + require.NoError(t, err) + expectedCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) + + // make expected branch + err = runCmd(tempDir, "git", "checkout", "-b", expectedBranch) + require.NoError(t, err) + + // checkout to base branch, ready to test + err = runCmd(tempDir, "git", "checkout", baseBranch) + require.NoError(t, err) + + out, err = client.CheckoutOrOrphan(expectedBranch, false) + require.NoError(t, err, "error output: ", out) + + // get current branch, verify current branch + gitCurrentBranch, err = outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + actualBranch := strings.TrimSpace(string(gitCurrentBranch)) + require.Equal(t, expectedBranch, actualBranch) + + // get current commit hash, verify current commit hash + // equal -> not orphan + gitCurrentCommitHash, err = outputCmd(tempDir, "git", "rev-parse", "HEAD") + require.NoError(t, err) + actualCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) + require.Equal(t, expectedCommitHash, actualCommitHash) + }) + + t.Run("orphan", func(t *testing.T) { + // not main or master + expectedBranch := "feature" + + // make origin git repository + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + originGitRepoUrl := fmt.Sprintf("file://%s", tempDir) + err = runCmd(tempDir, "git", "commit", "-m", "Second commit", "--allow-empty") + require.NoError(t, err) + + // get base branch + gitCurrentBranch, err := outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + baseBranch := strings.TrimSpace(string(gitCurrentBranch)) + + // make test dir + tempDir, err = os.MkdirTemp("", "") + require.NoError(t, err) + + client, err := NewClientExt(originGitRepoUrl, tempDir, NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + // set the author for the initial commit of the orphan branch + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: %s", out) + + err = client.Fetch("") + require.NoError(t, err) + + // checkout to origin base branch + err = runCmd(tempDir, "git", "checkout", baseBranch) + require.NoError(t, err) + + // get base commit + gitCurrentCommitHash, err := outputCmd(tempDir, "git", "rev-parse", "HEAD") + require.NoError(t, err) + baseCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) + + out, err = client.CheckoutOrOrphan(expectedBranch, false) + require.NoError(t, err, "error output: ", out) + + // get current branch, verify current branch + gitCurrentBranch, err = outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + actualBranch := strings.TrimSpace(string(gitCurrentBranch)) + require.Equal(t, expectedBranch, actualBranch) + + // check orphan branch + + // get current commit hash, verify current commit hash + // not equal -> orphan + gitCurrentCommitHash, err = outputCmd(tempDir, "git", "rev-parse", "HEAD") + require.NoError(t, err) + currentCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) + require.NotEqual(t, baseCommitHash, currentCommitHash) + + // get commit count on current branch, verify 1 -> orphan + gitCommitCount, err := outputCmd(tempDir, "git", "rev-list", "--count", actualBranch) + require.NoError(t, err) + require.Equal(t, "1", strings.TrimSpace(string(gitCommitCount))) + }) +} + +func Test_nativeGitClient_CheckoutOrNew(t *testing.T) { + t.Run("checkout to an existing branch", func(t *testing.T) { + // Example status + // * 57aef63 (feature) Second commit + // * a4fad22 (main) Initial commit + + // Test scenario + // given : main branch (w/ Initial commit) + // when : try to check out [main -> feature] + // then : feature branch (w/ Second commit) + + // not main or master + expectedBranch := "feature" + + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: %s", out) + + // get base branch + gitCurrentBranch, err := outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + baseBranch := strings.TrimSpace(string(gitCurrentBranch)) + + // make expected branch + err = runCmd(tempDir, "git", "checkout", "-b", expectedBranch) + require.NoError(t, err) + + // make expected commit + err = runCmd(tempDir, "git", "commit", "-m", "Second commit", "--allow-empty") + require.NoError(t, err) + + // get expected commit + expectedCommitHash, err := client.CommitSHA() + require.NoError(t, err) + + // checkout to base branch, ready to test + err = runCmd(tempDir, "git", "checkout", baseBranch) + require.NoError(t, err) + + out, err = client.CheckoutOrNew(expectedBranch, baseBranch, false) + require.NoError(t, err, "error output: ", out) + + // get current branch, verify current branch + gitCurrentBranch, err = outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + actualBranch := strings.TrimSpace(string(gitCurrentBranch)) + require.Equal(t, expectedBranch, actualBranch) + + // get current commit hash, verify current commit hash + actualCommitHash, err := client.CommitSHA() + require.NoError(t, err) + require.Equal(t, expectedCommitHash, actualCommitHash) + }) + + t.Run("new", func(t *testing.T) { + // Test scenario + // given : main branch (w/ Initial commit) + // * a4fad22 (main) Initial commit + // when : try to check out [main -> feature] + // then : feature branch (w/ Initial commit) + // * a4fad22 (feature, main) Initial commit + + // not main or master + expectedBranch := "feature" + + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + client, err := NewClientExt(fmt.Sprintf("file://%s", tempDir), tempDir, NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: %s", out) + + // get base branch + gitCurrentBranch, err := outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + baseBranch := strings.TrimSpace(string(gitCurrentBranch)) + + // get expected commit + expectedCommitHash, err := client.CommitSHA() + require.NoError(t, err) + + out, err = client.CheckoutOrNew(expectedBranch, baseBranch, false) + require.NoError(t, err, "error output: ", out) + + // get current branch, verify current branch + gitCurrentBranch, err = outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + actualBranch := strings.TrimSpace(string(gitCurrentBranch)) + require.Equal(t, expectedBranch, actualBranch) + + // get current commit hash, verify current commit hash + actualCommitHash, err := client.CommitSHA() + require.NoError(t, err) + require.Equal(t, expectedCommitHash, actualCommitHash) + }) +} + +func Test_nativeGitClient_RemoveContents(t *testing.T) { + // Example status + // 2 files : + // * /README.md + // * /scripts/startup.sh + + // given + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: ", out) + + err = runCmd(client.Root(), "touch", "README.md") + require.NoError(t, err) + + err = runCmd(client.Root(), "mkdir", "scripts") + require.NoError(t, err) + + err = runCmd(client.Root(), "touch", "scripts/startup.sh") + require.NoError(t, err) + + err = runCmd(client.Root(), "git", "add", "--all") + require.NoError(t, err) + + err = runCmd(client.Root(), "git", "commit", "-m", "Make files") + require.NoError(t, err) + + // when + out, err = client.RemoveContents() + require.NoError(t, err, "error output: ", out) + + // then + ls, err := outputCmd(client.Root(), "ls", "-l") + require.NoError(t, err) + require.Equal(t, "total 0", strings.TrimSpace(string(ls))) +} + +func Test_nativeGitClient_CommitAndPush(t *testing.T) { + tempDir, err := _createEmptyGitRepo() + require.NoError(t, err) + + // config receive.denyCurrentBranch updateInstead + // because local git init make a non-bare repository which cannot be pushed normally + err = runCmd(tempDir, "git", "config", "--local", "receive.denyCurrentBranch", "updateInstead") + require.NoError(t, err) + + // get branch + gitCurrentBranch, err := outputCmd(tempDir, "git", "rev-parse", "--abbrev-ref", "HEAD") + require.NoError(t, err) + branch := strings.TrimSpace(string(gitCurrentBranch)) + + client, err := NewClient(fmt.Sprintf("file://%s", tempDir), NopCreds{}, true, false, "", "") + require.NoError(t, err) + + err = client.Init() + require.NoError(t, err) + + out, err := client.SetAuthor("test", "test@example.com") + require.NoError(t, err, "error output: ", out) + + err = client.Fetch(branch) + require.NoError(t, err) + + out, err = client.Checkout(branch, false) + require.NoError(t, err, "error output: ", out) + + // make a file then commit and push + err = runCmd(client.Root(), "touch", "README.md") + require.NoError(t, err) + + out, err = client.CommitAndPush(branch, "docs: README") + require.NoError(t, err, "error output: %s", out) + + // get current commit hash of the cloned repository + expectedCommitHash, err := client.CommitSHA() + require.NoError(t, err) + + // get origin repository's current commit hash + gitCurrentCommitHash, err := outputCmd(tempDir, "git", "rev-parse", "HEAD") + require.NoError(t, err) + actualCommitHash := strings.TrimSpace(string(gitCurrentCommitHash)) + require.Equal(t, expectedCommitHash, actualCommitHash) +} diff --git a/util/git/creds.go b/util/git/creds.go index 5715925dcef9e..9f3675cac12a2 100644 --- a/util/git/creds.go +++ b/util/git/creds.go @@ -4,16 +4,20 @@ import ( "context" "crypto/sha256" "encoding/base64" + "encoding/hex" "encoding/json" "errors" "fmt" "io" + "net/http" "net/url" "os" "strconv" "strings" "time" + "github.com/google/go-github/v66/github" + "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -77,6 +81,8 @@ type CredsStore interface { type Creds interface { Environ() (io.Closer, []string, error) + // GetUserInfo gets the username and email address for the credentials, if they're available. + GetUserInfo(ctx context.Context) (string, string, error) } // nop implementation @@ -94,16 +100,24 @@ func (c NopCreds) Environ() (io.Closer, []string, error) { return NopCloser{}, nil, nil } +// GetUserInfo returns empty strings for user info +func (c NopCreds) GetUserInfo(ctx context.Context) (name string, email string, err error) { + return "", "", nil +} + var _ io.Closer = NopCloser{} type GenericHTTPSCreds interface { HasClientCert() bool GetClientCertData() string GetClientCertKey() string - Environ() (io.Closer, []string, error) + Creds } -var _ GenericHTTPSCreds = HTTPSCreds{} +var ( + _ GenericHTTPSCreds = HTTPSCreds{} + _ Creds = HTTPSCreds{} +) // HTTPS creds implementation type HTTPSCreds struct { @@ -141,6 +155,12 @@ func NewHTTPSCreds(username string, password string, clientCertData string, clie } } +// GetUserInfo returns the username and email address for the credentials, if they're available. +func (c HTTPSCreds) GetUserInfo(ctx context.Context) (string, string, error) { + // Email not implemented for HTTPS creds. + return c.username, "", nil +} + func (c HTTPSCreds) BasicAuthHeader() string { h := "Authorization: Basic " t := c.username + ":" + c.password @@ -231,6 +251,8 @@ func (c HTTPSCreds) GetClientCertKey() string { return c.clientCertKey } +var _ Creds = SSHCreds{} + // SSH implementation type SSHCreds struct { sshPrivateKey string @@ -245,6 +267,13 @@ func NewSSHCreds(sshPrivateKey string, caPath string, insecureIgnoreHostKey bool return SSHCreds{sshPrivateKey, caPath, insecureIgnoreHostKey, store, proxy, noProxy} } +// GetUserInfo returns empty strings for user info. +// TODO: Implement this method to return the username and email address for the credentials, if they're available. +func (c SSHCreds) GetUserInfo(ctx context.Context) (string, string, error) { + // User info not implemented for SSH creds. + return "", "", nil +} + type sshPrivateKeyFile string type authFilePaths []string @@ -414,6 +443,37 @@ func (g GitHubAppCreds) Environ() (io.Closer, []string, error) { }), env, nil } +// GetUserInfo returns the username and email address for the credentials, if they're available. +func (g GitHubAppCreds) GetUserInfo(ctx context.Context) (string, string, error) { + // We use the apps transport to get the app slug. + appTransport, err := g.getAppTransport() + if err != nil { + return "", "", fmt.Errorf("failed to create GitHub app transport: %w", err) + } + appClient := github.NewClient(&http.Client{Transport: appTransport}) + app, _, err := appClient.Apps.Get(ctx, "") + if err != nil { + return "", "", fmt.Errorf("failed to get app info: %w", err) + } + + // Then we use the installation transport to get the installation info. + appInstallTransport, err := g.getInstallationTransport() + if err != nil { + return "", "", fmt.Errorf("failed to get app installation: %w", err) + } + httpClient := http.Client{Transport: appInstallTransport} + client := github.NewClient(&httpClient) + + appLogin := fmt.Sprintf("%s[bot]", app.GetSlug()) + user, _, err := client.Users.Get(ctx, appLogin) + if err != nil { + return "", "", fmt.Errorf("failed to get app user info: %w", err) + } + authorName := user.GetLogin() + authorEmail := fmt.Sprintf("%d+%s@users.noreply.github.com", user.GetID(), user.GetLogin()) + return authorName, authorEmail, nil +} + // getAccessToken fetches GitHub token using the app id, install id, and private key. // the token is then cached for re-use. func (g GitHubAppCreds) getAccessToken() (string, error) { @@ -421,20 +481,53 @@ func (g GitHubAppCreds) getAccessToken() (string, error) { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() + itr, err := g.getInstallationTransport() + if err != nil { + return "", fmt.Errorf("failed to create GitHub app installation transport: %w", err) + } + + return itr.Token(ctx) +} + +// getAppTransport creates a new GitHub transport for the app +func (g GitHubAppCreds) getAppTransport() (*ghinstallation.AppsTransport, error) { + // GitHub API url + baseUrl := "https://api.github.com" + if g.baseURL != "" { + baseUrl = strings.TrimSuffix(g.baseURL, "/") + } + + // Create a new GitHub transport + c := GetRepoHTTPClient(baseUrl, g.insecure, g, g.proxy, g.noProxy) + itr, err := ghinstallation.NewAppsTransport(c.Transport, + g.appID, + []byte(g.privateKey), + ) + if err != nil { + return nil, fmt.Errorf("failed to initialize GitHub installation transport: %w", err) + } + + itr.BaseURL = baseUrl + + return itr, nil +} + +// getInstallationTransport creates a new GitHub transport for the app installation +func (g GitHubAppCreds) getInstallationTransport() (*ghinstallation.Transport, error) { // Compute hash of creds for lookup in cache h := sha256.New() _, err := h.Write([]byte(fmt.Sprintf("%s %d %d %s", g.privateKey, g.appID, g.appInstallId, g.baseURL))) if err != nil { - return "", err + return nil, fmt.Errorf("failed to get get SHA256 hash for GitHub app credentials: %w", err) } - key := fmt.Sprintf("%x", h.Sum(nil)) + key := hex.EncodeToString(h.Sum(nil)) // Check cache for GitHub transport which helps fetch an API token t, found := githubAppTokenCache.Get(key) if found { itr := t.(*ghinstallation.Transport) // This method caches the token and if it's expired retrieves a new one - return itr.Token(ctx) + return itr, nil } // GitHub API url @@ -451,7 +544,7 @@ func (g GitHubAppCreds) getAccessToken() (string, error) { []byte(g.privateKey), ) if err != nil { - return "", err + return nil, fmt.Errorf("failed to initialize GitHub installation transport: %w", err) } itr.BaseURL = baseUrl @@ -459,7 +552,7 @@ func (g GitHubAppCreds) getAccessToken() (string, error) { // Add transport to cache githubAppTokenCache.Set(key, itr, time.Minute*60) - return itr.Token(ctx) + return itr, nil } func (g GitHubAppCreds) HasClientCert() bool { @@ -474,6 +567,8 @@ func (g GitHubAppCreds) GetClientCertKey() string { return g.clientCertKey } +var _ Creds = GoogleCloudCreds{} + // GoogleCloudCreds to authenticate to Google Cloud Source repositories type GoogleCloudCreds struct { creds *google.Credentials @@ -489,6 +584,16 @@ func NewGoogleCloudCreds(jsonData string, store CredsStore) GoogleCloudCreds { return GoogleCloudCreds{creds, store} } +// GetUserInfo returns the username and email address for the credentials, if they're available. +// TODO: implement getting email instead of just username. +func (c GoogleCloudCreds) GetUserInfo(ctx context.Context) (string, string, error) { + username, err := c.getUsername() + if err != nil { + return "", "", fmt.Errorf("failed to get username from creds: %w", err) + } + return username, "", nil +} + func (c GoogleCloudCreds) Environ() (io.Closer, []string, error) { username, err := c.getUsername() if err != nil { @@ -543,7 +648,7 @@ func (c GoogleCloudCreds) getAccessToken() (string, error) { if err != nil { return "", err } - key := fmt.Sprintf("%x", h.Sum(nil)) + key := hex.EncodeToString(h.Sum(nil)) t, found := googleCloudTokenSource.Get(key) if found { diff --git a/util/git/git.go b/util/git/git.go index 3a087aeb00096..ea2f310b0f7fb 100644 --- a/util/git/git.go +++ b/util/git/git.go @@ -1,6 +1,7 @@ package git import ( + "fmt" "net/url" "regexp" "strings" @@ -35,11 +36,21 @@ func IsTruncatedCommitSHA(sha string) bool { // SameURL returns whether or not the two repository URLs are equivalent in location func SameURL(leftRepo, rightRepo string) bool { - normalLeft := NormalizeGitURL(leftRepo) - normalRight := NormalizeGitURL(rightRepo) + normalLeft := NormalizeGitURLAllowInvalid(leftRepo) + normalRight := NormalizeGitURLAllowInvalid(rightRepo) return normalLeft != "" && normalRight != "" && normalLeft == normalRight } +// Similar to NormalizeGitURL, except returning an original url if the url is invalid. +// Needed to allow a deletion of repos with invalid urls. See https://github.com/argoproj/argo-cd/issues/20921. +func NormalizeGitURLAllowInvalid(repo string) string { + normalized := NormalizeGitURL(repo) + if normalized == "" { + return repo + } + return normalized +} + // NormalizeGitURL normalizes a git URL for purposes of comparison, as well as preventing redundant // local clones (by normalizing various forms of a URL to a consistent location). // Prefer using SameURL() over this function when possible. This algorithm may change over time @@ -84,10 +95,13 @@ func IsHTTPURL(url string) bool { // TestRepo tests if a repo exists and is accessible with the given credentials func TestRepo(repo string, creds Creds, insecure bool, enableLfs bool, proxy string, noProxy string) error { - clnt, err := NewClient(repo, creds, insecure, enableLfs, proxy, noProxy) + client, err := NewClient(repo, creds, insecure, enableLfs, proxy, noProxy) + if err != nil { + return fmt.Errorf("unable to initialize git client: %w", err) + } + _, err = client.LsRemote("HEAD") if err != nil { - return err + return fmt.Errorf("unable to ls-remote HEAD on repository: %w", err) } - _, err = clnt.LsRemote("HEAD") - return err + return nil } diff --git a/util/git/git_test.go b/util/git/git_test.go index bfa2905e7f518..f06df14c070ea 100644 --- a/util/git/git_test.go +++ b/util/git/git_test.go @@ -233,15 +233,10 @@ func TestLsRemote(t *testing.T) { expectedCommit: "ff87d8cb9e669d3738434733ecba3c6dd2c64d70", }, { - name: "should resolve a pined tag with semantic versioning", + name: "should resolve a pinned tag with semantic versioning", revision: "v0.8.0", expectedCommit: "d7c04ae24c16f8ec611b0331596fbc595537abe9", }, - { - name: "should resolve a pined tag with semantic versioning without the 'v' prefix", - revision: "0.8.0", - expectedCommit: "d7c04ae24c16f8ec611b0331596fbc595537abe9", - }, { name: "should resolve a range tag with semantic versioning", revision: "v0.8.*", // it should resolve to v0.8.2 @@ -299,7 +294,7 @@ func TestLsRemote(t *testing.T) { for _, revision := range xfail { _, err := clnt.LsRemote(revision) - assert.ErrorContains(t, err, "Unable to resolve") + assert.ErrorContains(t, err, "unable to resolve") } }) } @@ -325,7 +320,7 @@ func TestLFSClient(t *testing.T) { err = client.Fetch("") require.NoError(t, err) - err = client.Checkout(commitSHA, true) + _, err = client.Checkout(commitSHA, true) require.NoError(t, err) largeFiles, err := client.LsLargeFiles() @@ -363,7 +358,7 @@ func TestVerifyCommitSignature(t *testing.T) { commitSHA, err := client.LsRemote("HEAD") require.NoError(t, err) - err = client.Checkout(commitSHA, true) + _, err = client.Checkout(commitSHA, true) require.NoError(t, err) // 28027897aad1262662096745f2ce2d4c74d02b7f is a commit that is signed in the repo @@ -420,7 +415,7 @@ func TestNewFactory(t *testing.T) { err = client.Fetch("") require.NoError(t, err) - err = client.Checkout(commitSHA, true) + _, err = client.Checkout(commitSHA, true) require.NoError(t, err) revisionMetadata, err := client.RevisionMetadata(commitSHA) diff --git a/util/git/mocks/Client.go b/util/git/mocks/Client.go index 490aa4e99b90d..9357264e3bdd6 100644 --- a/util/git/mocks/Client.go +++ b/util/git/mocks/Client.go @@ -43,21 +43,115 @@ func (_m *Client) ChangedFiles(revision string, targetRevision string) ([]string } // Checkout provides a mock function with given fields: revision, submoduleEnabled -func (_m *Client) Checkout(revision string, submoduleEnabled bool) error { +func (_m *Client) Checkout(revision string, submoduleEnabled bool) (string, error) { ret := _m.Called(revision, submoduleEnabled) if len(ret) == 0 { panic("no return value specified for Checkout") } - var r0 error - if rf, ok := ret.Get(0).(func(string, bool) error); ok { + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) (string, error)); ok { + return rf(revision, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, bool) string); ok { r0 = rf(revision, submoduleEnabled) } else { - r0 = ret.Error(0) + r0 = ret.Get(0).(string) } - return r0 + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(revision, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckoutOrNew provides a mock function with given fields: branch, base, submoduleEnabled +func (_m *Client) CheckoutOrNew(branch string, base string, submoduleEnabled bool) (string, error) { + ret := _m.Called(branch, base, submoduleEnabled) + + if len(ret) == 0 { + panic("no return value specified for CheckoutOrNew") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string, bool) (string, error)); ok { + return rf(branch, base, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, string, bool) string); ok { + r0 = rf(branch, base, submoduleEnabled) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string, bool) error); ok { + r1 = rf(branch, base, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckoutOrOrphan provides a mock function with given fields: branch, submoduleEnabled +func (_m *Client) CheckoutOrOrphan(branch string, submoduleEnabled bool) (string, error) { + ret := _m.Called(branch, submoduleEnabled) + + if len(ret) == 0 { + panic("no return value specified for CheckoutOrOrphan") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, bool) (string, error)); ok { + return rf(branch, submoduleEnabled) + } + if rf, ok := ret.Get(0).(func(string, bool) string); ok { + r0 = rf(branch, submoduleEnabled) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, bool) error); ok { + r1 = rf(branch, submoduleEnabled) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitAndPush provides a mock function with given fields: branch, message +func (_m *Client) CommitAndPush(branch string, message string) (string, error) { + ret := _m.Called(branch, message) + + if len(ret) == 0 { + panic("no return value specified for CommitAndPush") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(branch, message) + } + if rf, ok := ret.Get(0).(func(string, string) string); ok { + r0 = rf(branch, message) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(branch, message) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // CommitSHA provides a mock function with given fields: @@ -278,6 +372,34 @@ func (_m *Client) LsRemote(revision string) (string, error) { return r0, r1 } +// RemoveContents provides a mock function with given fields: +func (_m *Client) RemoveContents() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for RemoveContents") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // RevisionMetadata provides a mock function with given fields: revision func (_m *Client) RevisionMetadata(revision string) (*git.RevisionMetadata, error) { ret := _m.Called(revision) @@ -326,6 +448,34 @@ func (_m *Client) Root() string { return r0 } +// SetAuthor provides a mock function with given fields: name, email +func (_m *Client) SetAuthor(name string, email string) (string, error) { + ret := _m.Called(name, email) + + if len(ret) == 0 { + panic("no return value specified for SetAuthor") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(name, email) + } + if rf, ok := ret.Get(0).(func(string, string) string); ok { + r0 = rf(name, email) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(name, email) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Submodule provides a mock function with given fields: func (_m *Client) Submodule() error { ret := _m.Called() diff --git a/util/glob/glob.go b/util/glob/glob.go index 0ef7cda28635a..c96681b2aed93 100644 --- a/util/glob/glob.go +++ b/util/glob/glob.go @@ -5,6 +5,7 @@ import ( log "github.com/sirupsen/logrus" ) +// Match tries to match a text with a given glob pattern. func Match(pattern, text string, separators ...rune) bool { compiledGlob, err := glob.Compile(pattern, separators...) if err != nil { @@ -13,3 +14,13 @@ func Match(pattern, text string, separators ...rune) bool { } return compiledGlob.Match(text) } + +// MatchWithError tries to match a text with a given glob pattern. +// returns error if the glob pattern fails to compile. +func MatchWithError(pattern, text string, separators ...rune) (bool, error) { + compiledGlob, err := glob.Compile(pattern, separators...) + if err != nil { + return false, err + } + return compiledGlob.Match(text), nil +} diff --git a/util/glob/glob_test.go b/util/glob/glob_test.go index a0a3995382c92..201fac2acfaff 100644 --- a/util/glob/glob_test.go +++ b/util/glob/glob_test.go @@ -3,7 +3,7 @@ package glob import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_Match(t *testing.T) { @@ -24,7 +24,7 @@ func Test_Match(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res := Match(tt.pattern, tt.input) - assert.Equal(t, tt.result, res) + require.Equal(t, tt.result, res) }) } } @@ -53,7 +53,36 @@ func Test_MatchList(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res := MatchStringInList(tt.list, tt.input, tt.patternMatch) - assert.Equal(t, tt.result, res) + require.Equal(t, tt.result, res) + }) + } +} + +func Test_MatchWithError(t *testing.T) { + tests := []struct { + name string + input string + pattern string + result bool + expectedErr string + }{ + {"Exact match", "hello", "hello", true, ""}, + {"Non-match exact", "hello", "hell", false, ""}, + {"Long glob match", "hello", "hell*", true, ""}, + {"Short glob match", "hello", "h*", true, ""}, + {"Glob non-match", "hello", "e*", false, ""}, + {"Invalid pattern", "e[[a*", "e[[a*", false, "unexpected end of input"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, err := MatchWithError(tt.pattern, tt.input) + require.Equal(t, tt.result, res) + if tt.expectedErr == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tt.expectedErr) + } }) } } diff --git a/util/gpg/gpg_test.go b/util/gpg/gpg_test.go index 377de31f0260b..e279f1e9ad554 100644 --- a/util/gpg/gpg_test.go +++ b/util/gpg/gpg_test.go @@ -28,6 +28,7 @@ var syncTestSources = map[string]string{ // Helper function to create temporary GNUPGHOME func initTempDir(t *testing.T) string { + t.Helper() // Intentionally avoid using t.TempDir. That function creates really long paths, which can exceed the socket file // path length on some OSes. The GPG tests rely on sockets. p, err := os.MkdirTemp(os.TempDir(), "") @@ -98,8 +99,7 @@ func Test_GPG_InitializeGnuPG(t *testing.T) { // we need to error out t.Setenv(common.EnvGnuPGHome, f.Name()) err = InitializeGnuPG() - require.Error(t, err) - assert.Contains(t, err.Error(), "does not point to a directory") + assert.ErrorContains(t, err, "does not point to a directory") }) t.Run("Unaccessible GNUPGHOME", func(t *testing.T) { diff --git a/util/grpc/useragent_test.go b/util/grpc/useragent_test.go index bcc3930bec285..6520acf005221 100644 --- a/util/grpc/useragent_test.go +++ b/util/grpc/useragent_test.go @@ -35,8 +35,7 @@ func Test_UserAgentEnforcer(t *testing.T) { md := metadata.New(map[string]string{"user-agent": "argo-cd/3.0"}) ctx := metadata.NewIncomingContext(context.Background(), md) err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) - require.Error(t, err) - require.Contains(t, err.Error(), "unsatisfied client version constraint") + require.ErrorContains(t, err, "unsatisfied client version constraint") }) t.Run("Test legacy user-agent", func(t *testing.T) { clientName := "argo-cd" @@ -45,8 +44,7 @@ func Test_UserAgentEnforcer(t *testing.T) { md := metadata.New(map[string]string{"user-agent": "grpc-go/1.15.0"}) ctx := metadata.NewIncomingContext(context.Background(), md) err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) - require.Error(t, err) - require.Contains(t, err.Error(), "unsatisfied client version constraint") + require.ErrorContains(t, err, "unsatisfied client version constraint") }) t.Run("Test invalid version", func(t *testing.T) { clientName := "argo-cd" @@ -55,7 +53,6 @@ func Test_UserAgentEnforcer(t *testing.T) { md := metadata.New(map[string]string{"user-agent": "argo-cd/super"}) ctx := metadata.NewIncomingContext(context.Background(), md) err := userAgentEnforcer(ctx, clientName, constraintStr, semverConstraint) - require.Error(t, err) - require.Contains(t, err.Error(), "could not parse version") + require.ErrorContains(t, err, "could not parse version") }) } diff --git a/util/healthz/healthz_test.go b/util/healthz/healthz_test.go index 5a0042ab6e765..cf68eb419b708 100644 --- a/util/healthz/healthz_test.go +++ b/util/healthz/healthz_test.go @@ -5,6 +5,8 @@ import ( "net" "net/http" "testing" + + "github.com/stretchr/testify/require" ) func TestHealthCheck(t *testing.T) { @@ -41,18 +43,11 @@ func TestHealthCheck(t *testing.T) { server := "http://" + address resp, err := http.Get(server + "/healthz") - if err != nil { - t.Fatal(err) - } - - if resp.StatusCode != http.StatusOK { - t.Fatalf("Was expecting status code 200 from health check, but got %d instead", resp.StatusCode) - } + require.NoError(t, err) + require.Equalf(t, http.StatusOK, resp.StatusCode, "Was expecting status code 200 from health check, but got %d instead", resp.StatusCode) sentinel = true resp, _ = http.Get(server + "/healthz") - if resp.StatusCode != http.StatusServiceUnavailable { - t.Fatalf("Was expecting status code 503 from health check, but got %d instead", resp.StatusCode) - } + require.Equalf(t, http.StatusServiceUnavailable, resp.StatusCode, "Was expecting status code 503 from health check, but got %d instead", resp.StatusCode) } diff --git a/util/helm/client.go b/util/helm/client.go index 3ddbcec4333a6..d9972adb04968 100644 --- a/util/helm/client.go +++ b/util/helm/client.go @@ -25,6 +25,7 @@ import ( "gopkg.in/yaml.v2" "oras.land/oras-go/v2/registry/remote" "oras.land/oras-go/v2/registry/remote/auth" + "oras.land/oras-go/v2/registry/remote/credentials" "github.com/argoproj/argo-cd/v2/util/cache" argoio "github.com/argoproj/argo-cd/v2/util/io" @@ -447,13 +448,23 @@ func (c *nativeHelmChart) GetTags(chart string, noCache bool) (*TagsList, error) }} repoHost, _, _ := strings.Cut(tagsURL, "/") + credential := auth.StaticCredential(repoHost, auth.Credential{ + Username: c.creds.Username, + Password: c.creds.Password, + }) + + // Try to fallback to the environment config, but we shouldn't error if the file is not set + if c.creds.Username == "" && c.creds.Password == "" { + store, _ := credentials.NewStoreFromDocker(credentials.StoreOptions{}) + if store != nil { + credential = credentials.Credential(store) + } + } + repo.Client = &auth.Client{ - Client: client, - Cache: nil, - Credential: auth.StaticCredential(repoHost, auth.Credential{ - Username: c.creds.Username, - Password: c.creds.Password, - }), + Client: client, + Cache: nil, + Credential: credential, } ctx := context.Background() diff --git a/util/helm/client_test.go b/util/helm/client_test.go index f03bd15bf096d..97c27d6c1f62c 100644 --- a/util/helm/client_test.go +++ b/util/helm/client_test.go @@ -9,6 +9,7 @@ import ( "net/http/httptest" "net/url" "os" + "path/filepath" "strings" "testing" @@ -184,10 +185,7 @@ func TestGetTagsFromUrl(t *testing.T) { } } w.WriteHeader(http.StatusOK) - err := json.NewEncoder(w).Encode(responseTags) - if err != nil { - t.Fatal(err) - } + require.NoError(t, json.NewEncoder(w).Encode(responseTags)) })) client := NewClient(server.URL, Creds{InsecureSkipVerify: true}, true, "", "") @@ -214,17 +212,21 @@ func TestGetTagsFromUrl(t *testing.T) { } func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { + username := "my-username" + password := "my-password" + expectedAuthorization := "Basic bXktdXNlcm5hbWU6bXktcGFzc3dvcmQ=" // base64(user:password) server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t.Logf("called %s", r.URL.Path) authorization := r.Header.Get("Authorization") + if authorization == "" { w.Header().Set("WWW-Authenticate", `Basic realm="helm repo to get tags"`) w.WriteHeader(http.StatusUnauthorized) return } - t.Logf("authorization received %s", authorization) + assert.Equal(t, expectedAuthorization, authorization) responseTags := TagsList{ Tags: []string{ @@ -238,16 +240,98 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - err := json.NewEncoder(w).Encode(responseTags) - if err != nil { - t.Fatal(err) + require.NoError(t, json.NewEncoder(w).Encode(responseTags)) + })) + t.Cleanup(server.Close) + + serverURL, err := url.Parse(server.URL) + require.NoError(t, err) + + testCases := []struct { + name string + repoURL string + }{ + { + name: "should login correctly when the repo path is in the server root with http scheme", + repoURL: server.URL, + }, + { + name: "should login correctly when the repo path is not in the server root with http scheme", + repoURL: fmt.Sprintf("%s/my-repo", server.URL), + }, + { + name: "should login correctly when the repo path is in the server root without http scheme", + repoURL: serverURL.Host, + }, + { + name: "should login correctly when the repo path is not in the server root without http scheme", + repoURL: fmt.Sprintf("%s/my-repo", serverURL.Host), + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + client := NewClient(testCase.repoURL, Creds{ + InsecureSkipVerify: true, + Username: username, + Password: password, + }, true, "", "") + + tags, err := client.GetTags("mychart", true) + + require.NoError(t, err) + assert.ElementsMatch(t, tags.Tags, []string{ + "2.8.0", + "2.8.0-prerelease", + "2.8.0+build", + "2.8.0-prerelease+build", + "2.8.0-prerelease.1+build.1234", + }) + }) + } +} + +func TestGetTagsFromURLEnvironmentAuthentication(t *testing.T) { + bearerToken := "Zm9vOmJhcg==" + expectedAuthorization := "Basic " + bearerToken + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + t.Logf("called %s", r.URL.Path) + + authorization := r.Header.Get("Authorization") + if authorization == "" { + w.Header().Set("WWW-Authenticate", `Basic realm="helm repo to get tags"`) + w.WriteHeader(http.StatusUnauthorized) + return + } + + assert.Equal(t, expectedAuthorization, authorization) + + responseTags := TagsList{ + Tags: []string{ + "2.8.0", + "2.8.0-prerelease", + "2.8.0_build", + "2.8.0-prerelease_build", + "2.8.0-prerelease.1_build.1234", + }, } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + require.NoError(t, json.NewEncoder(w).Encode(responseTags)) })) t.Cleanup(server.Close) serverURL, err := url.Parse(server.URL) require.NoError(t, err) + tempDir := t.TempDir() + configPath := filepath.Join(tempDir, "config.json") + t.Setenv("DOCKER_CONFIG", tempDir) + + config := fmt.Sprintf(`{"auths":{"%s":{"auth":"%s"}}}`, server.URL, bearerToken) + require.NoError(t, os.WriteFile(configPath, []byte(config), 0o666)) + testCases := []struct { name string repoURL string @@ -274,8 +358,6 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { client := NewClient(testCase.repoURL, Creds{ InsecureSkipVerify: true, - Username: "my-username", - Password: "my-password", }, true, "", "") tags, err := client.GetTags("mychart", true) diff --git a/util/helm/cmd.go b/util/helm/cmd.go index 6b0e30ed2fe75..28b458fa51c88 100644 --- a/util/helm/cmd.go +++ b/util/helm/cmd.go @@ -338,23 +338,42 @@ type TemplateOpts struct { Values []pathutil.ResolvedFilePath // ExtraValues is the randomly-generated path to the temporary values file holding the contents of // spec.source.helm.values/valuesObject. - ExtraValues pathutil.ResolvedFilePath - SkipCrds bool + ExtraValues pathutil.ResolvedFilePath + SkipCrds bool + SkipSchemaValidation bool + SkipTests bool } -var ( - re = regexp.MustCompile(`([^\\]),`) - apiVersionsRemover = regexp.MustCompile(`(--api-versions [^ ]+ )+`) -) - func cleanSetParameters(val string) string { // `{}` equal helm list parameters format, so don't escape `,`. if strings.HasPrefix(val, `{`) && strings.HasSuffix(val, `}`) { return val } - return re.ReplaceAllString(val, `$1\,`) + + val = replaceAllWithLookbehind(val, ',', `\,`, '\\') + return val } +func replaceAllWithLookbehind(val string, old rune, new string, lookbehind rune) string { + var result strings.Builder + var prevR rune + for _, r := range val { + if r == old { + if prevR != lookbehind { + result.WriteString(new) + } else { + result.WriteRune(old) + } + } else { + result.WriteRune(r) + } + prevR = r + } + return result.String() +} + +var apiVersionsRemover = regexp.MustCompile(`(--api-versions [^ ]+ )+`) + func (c *Cmd) template(chartPath string, opts *TemplateOpts) (string, string, error) { if callback, err := cleanupChartLockFile(filepath.Clean(path.Join(c.WorkDir, chartPath))); err == nil { defer callback() @@ -391,6 +410,12 @@ func (c *Cmd) template(chartPath string, opts *TemplateOpts) (string, string, er if !opts.SkipCrds { args = append(args, "--include-crds") } + if opts.SkipSchemaValidation { + args = append(args, "--skip-schema-validation") + } + if opts.SkipTests { + args = append(args, "--skip-tests") + } out, command, err := c.run(args...) if err != nil { diff --git a/util/helm/helm_test.go b/util/helm/helm_test.go index 8468b9f36624b..2d72a87745f25 100644 --- a/util/helm/helm_test.go +++ b/util/helm/helm_test.go @@ -166,6 +166,8 @@ func TestHelmArgCleaner(t *testing.T) { `not, clean`: `not\, clean`, `a\,b,c`: `a\,b\,c`, `{a,b,c}`: `{a,b,c}`, + `,,,,,\,`: `\,\,\,\,\,\,`, + `\,,\\,,`: `\,\,\\,\,`, } { cleaned := cleanSetParameters(input) assert.Equal(t, expected, cleaned) @@ -233,3 +235,20 @@ func TestSkipCrds(t *testing.T) { require.NoError(t, err) require.Empty(t, objs) } + +func TestSkipTests(t *testing.T) { + h, err := NewHelmApp("./testdata/tests", nil, false, "", "", "", false) + require.NoError(t, err) + + objs, err := template(h, &TemplateOpts{SkipTests: false}) + require.NoError(t, err) + require.Len(t, objs, 1) + + objs, err = template(h, &TemplateOpts{}) + require.NoError(t, err) + require.Len(t, objs, 1) + + objs, err = template(h, &TemplateOpts{SkipTests: true}) + require.NoError(t, err) + require.Empty(t, objs) +} diff --git a/util/helm/testdata/tests/Chart.yaml b/util/helm/testdata/tests/Chart.yaml new file mode 100644 index 0000000000000..2b93d488735d1 --- /dev/null +++ b/util/helm/testdata/tests/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v1 +version: 1.0.0 +name: tests diff --git a/util/helm/testdata/tests/templates/tests/test-pod.yaml b/util/helm/testdata/tests/templates/tests/test-pod.yaml new file mode 100644 index 0000000000000..ea9fb339f101d --- /dev/null +++ b/util/helm/testdata/tests/templates/tests/test-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-pod + annotations: + "helm.sh/hook": test +spec: + containers: + - name: test + image: busybox + command: ['sh', '-c', 'echo Test'] \ No newline at end of file diff --git a/util/io/files/secure_mkdir_default.go b/util/io/files/secure_mkdir_default.go new file mode 100644 index 0000000000000..fe7733e2d071f --- /dev/null +++ b/util/io/files/secure_mkdir_default.go @@ -0,0 +1,25 @@ +//go:build !linux + +package files + +import ( + "fmt" + "os" + + securejoin "github.com/cyphar/filepath-securejoin" +) + +// SecureMkdirAll creates a directory with the given mode and returns the full path to the directory. It prevents +// directory traversal attacks by ensuring the path is within the root directory. The path is constructed as if the +// given root is the root of the filesystem. So anything traversing outside the root is simply removed from the path. +func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) { + fullPath, err := securejoin.SecureJoin(root, unsafePath) + if err != nil { + return "", fmt.Errorf("failed to construct secure path: %w", err) + } + err = os.MkdirAll(fullPath, mode) + if err != nil { + return "", fmt.Errorf("failed to create directory: %w", err) + } + return fullPath, nil +} diff --git a/util/io/files/secure_mkdir_linux.go b/util/io/files/secure_mkdir_linux.go new file mode 100644 index 0000000000000..14f727dda480d --- /dev/null +++ b/util/io/files/secure_mkdir_linux.go @@ -0,0 +1,25 @@ +//go:build linux + +package files + +import ( + "fmt" + "os" + + securejoin "github.com/cyphar/filepath-securejoin" +) + +// SecureMkdirAll creates a directory with the given mode and returns the full path to the directory. It prevents +// directory traversal attacks by ensuring the path is within the root directory. The path is constructed as if the +// given root is the root of the filesystem. So anything traversing outside the root is simply removed from the path. +func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) { + err := securejoin.MkdirAll(root, unsafePath, int(mode)) + if err != nil { + return "", fmt.Errorf("failed to make directory: %w", err) + } + fullPath, err := securejoin.SecureJoin(root, unsafePath) + if err != nil { + return "", fmt.Errorf("failed to construct secure path: %w", err) + } + return fullPath, nil +} diff --git a/util/io/files/secure_mkdir_test.go b/util/io/files/secure_mkdir_test.go new file mode 100644 index 0000000000000..e696629235404 --- /dev/null +++ b/util/io/files/secure_mkdir_test.go @@ -0,0 +1,67 @@ +package files + +import ( + "os" + "path" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSecureMkdirAllDefault(t *testing.T) { + root := t.TempDir() + + unsafePath := "test/dir" + fullPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + + expectedPath := path.Join(root, unsafePath) + assert.Equal(t, expectedPath, fullPath) +} + +func TestSecureMkdirAllWithExistingDir(t *testing.T) { + root := t.TempDir() + unsafePath := "existing/dir" + + fullPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + + newPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + assert.Equal(t, fullPath, newPath) +} + +func TestSecureMkdirAllWithFile(t *testing.T) { + root := t.TempDir() + unsafePath := "file.txt" + + filePath := filepath.Join(root, unsafePath) + err := os.WriteFile(filePath, []byte("test"), os.ModePerm) + require.NoError(t, err) + + // Should fail because there is a file at the path + _, err = SecureMkdirAll(root, unsafePath, os.ModePerm) + require.Error(t, err) +} + +func TestSecureMkdirAllDotDotPath(t *testing.T) { + root := t.TempDir() + unsafePath := "../outside" + + fullPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + + expectedPath := filepath.Join(root, "outside") + assert.Equal(t, expectedPath, fullPath) + + info, err := os.Stat(fullPath) + require.NoError(t, err) + assert.True(t, info.IsDir()) + + relPath, err := filepath.Rel(root, fullPath) + require.NoError(t, err) + assert.False(t, strings.HasPrefix(relPath, "..")) +} diff --git a/util/io/files/tar_test.go b/util/io/files/tar_test.go index f8b140b5dc658..3ef7d24e0e53e 100644 --- a/util/io/files/tar_test.go +++ b/util/io/files/tar_test.go @@ -108,9 +108,7 @@ func TestUntgz(t *testing.T) { createTmpDir := func(t *testing.T) string { t.Helper() tmpDir, err := os.MkdirTemp(getTestDataDir(t), "") - if err != nil { - t.Fatalf("error creating tmpDir: %s", err) - } + require.NoErrorf(t, err, "error creating tmpDir: %s", err) return tmpDir } deleteTmpDir := func(t *testing.T, dirname string) { @@ -123,16 +121,11 @@ func TestUntgz(t *testing.T) { createTgz := func(t *testing.T, fromDir, destDir string) *os.File { t.Helper() f, err := os.CreateTemp(destDir, "") - if err != nil { - t.Fatalf("error creating tmpFile in %q: %s", destDir, err) - } + require.NoErrorf(t, err, "error creating tmpFile in %q: %s", destDir, err) _, err = files.Tgz(fromDir, nil, nil, f) - if err != nil { - t.Fatalf("error during Tgz: %s", err) - } - if _, err := f.Seek(0, io.SeekStart); err != nil { - t.Fatalf("seek error: %s", err) - } + require.NoErrorf(t, err, "error during Tgz: %s", err) + _, err = f.Seek(0, io.SeekStart) + require.NoErrorf(t, err, "seek error: %s", err) return f } readFiles := func(t *testing.T, basedir string) map[string]string { @@ -154,9 +147,7 @@ func TestUntgz(t *testing.T) { names[relativePath] = link return nil }) - if err != nil { - t.Fatalf("error reading files: %s", err) - } + require.NoErrorf(t, err, "error reading files: %s", err) return names } t.Run("will untgz successfully", func(t *testing.T) { @@ -195,8 +186,7 @@ func TestUntgz(t *testing.T) { err := files.Untgz(destDir, tgzFile, math.MaxInt64, false) // then - require.Error(t, err) - assert.Contains(t, err.Error(), "illegal filepath in symlink") + assert.ErrorContains(t, err, "illegal filepath in symlink") }) t.Run("preserves file mode", func(t *testing.T) { @@ -252,11 +242,13 @@ func read(tgz *os.File) (map[string]string, error) { // getTestAppDir will return the full path of the app dir under // the 'testdata' folder. func getTestAppDir(t *testing.T) string { + t.Helper() return filepath.Join(getTestDataDir(t), "app") } // getTestDataDir will return the full path of the testdata dir // under the running test folder. func getTestDataDir(t *testing.T) string { + t.Helper() return filepath.Join(test.GetTestDir(t), "testdata") } diff --git a/util/io/path/resolved_test.go b/util/io/path/resolved_test.go index deecbec31055a..36472e8788716 100644 --- a/util/io/path/resolved_test.go +++ b/util/io/path/resolved_test.go @@ -111,8 +111,7 @@ func Test_resolveFilePath(t *testing.T) { }) t.Run("Error on path resolving outside repository root", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl("/foo/bar", "/foo", "baz/../../../bim.yaml", allowedRemoteProtocols) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) assert.Equal(t, "", string(p)) }) @@ -152,29 +151,25 @@ func Test_resolveFilePath(t *testing.T) { }) t.Run("Overlapping root prefix without trailing slash", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl(".", "/foo", "../foo2/baz.yaml", allowedRemoteProtocols) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) assert.Equal(t, "", string(p)) }) t.Run("Overlapping root prefix with trailing slash", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "../foo2/baz.yaml", allowedRemoteProtocols) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) assert.Equal(t, "", string(p)) }) t.Run("Garbage input as values file", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "kfdj\\ks&&&321209.,---e32908923%$§!\"", allowedRemoteProtocols) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) assert.Equal(t, "", string(p)) }) t.Run("NUL-byte path input as values file", func(t *testing.T) { p, remote, err := ResolveValueFilePathOrUrl(".", "/foo/", "\000", allowedRemoteProtocols) - require.Error(t, err) - assert.Contains(t, err.Error(), "outside repository root") + require.ErrorContains(t, err, "outside repository root") assert.False(t, remote) assert.Equal(t, "", string(p)) }) diff --git a/util/jwt/jwt_test.go b/util/jwt/jwt_test.go index 7daf855e3d9fb..1b0ac87fe9752 100644 --- a/util/jwt/jwt_test.go +++ b/util/jwt/jwt_test.go @@ -1,7 +1,6 @@ package jwt import ( - "fmt" "testing" "time" @@ -45,7 +44,7 @@ func TestIssuedAtTime_Int64(t *testing.T) { claims := jwt.MapClaims{"iat": int64(1606831200)} issuedAt, err := IssuedAtTime(claims) require.NoError(t, err) - str := fmt.Sprint(issuedAt.UTC().Format("Mon Jan _2 15:04:05 2006")) + str := issuedAt.UTC().Format("Mon Jan _2 15:04:05 2006") assert.Equal(t, "Tue Dec 1 14:00:00 2020", str) } diff --git a/util/kube/failureretrywrapper.go b/util/kube/failureretrywrapper.go index 5551a36cf15ce..f9d66e89105fd 100644 --- a/util/kube/failureretrywrapper.go +++ b/util/kube/failureretrywrapper.go @@ -27,7 +27,7 @@ func shouldRetry(counter int, r *http.Request, response *http.Response, err erro return true } } - if response != nil && (response.StatusCode == 504 || response.StatusCode == 503) { + if response != nil && (response.StatusCode == http.StatusGatewayTimeout || response.StatusCode == http.StatusServiceUnavailable) { return true } diff --git a/util/kube/kube.go b/util/kube/kube.go index a982460e331e6..aa96dfc4d3fff 100644 --- a/util/kube/kube.go +++ b/util/kube/kube.go @@ -161,6 +161,30 @@ func RemoveLabel(un *unstructured.Unstructured, key string) error { return nil } +// RemoveAnnotation removes annotation with the specified name +func RemoveAnnotation(un *unstructured.Unstructured, key string) error { + annotations, err := nestedNullableStringMap(un.Object, "metadata", "annotations") + if err != nil { + return fmt.Errorf("failed to get annotations for %s %s/%s: %w", un.GroupVersionKind().String(), un.GetNamespace(), un.GetName(), err) + } + if annotations == nil { + return nil + } + + for k := range annotations { + if k == key { + delete(annotations, k) + if len(annotations) == 0 { + un.SetAnnotations(nil) + } else { + un.SetAnnotations(annotations) + } + break + } + } + return nil +} + // nestedNullableStringMap returns a copy of map[string]string value of a nested field. // Returns false if value is not found and an error if not one of map[string]interface{} or nil, or contains non-string values in the map. func nestedNullableStringMap(obj map[string]interface{}, fields ...string) (map[string]string, error) { diff --git a/util/kube/util_test.go b/util/kube/util_test.go index a8a674bdda741..ac3e5a35276e4 100644 --- a/util/kube/util_test.go +++ b/util/kube/util_test.go @@ -47,7 +47,7 @@ func Test_CreateOrUpdateSecretField(t *testing.T) { "annotation3": "foo", } - client := fake.NewSimpleClientset(secret) + client := fake.NewClientset(secret) t.Run("Change field in existing secret", func(t *testing.T) { ku := NewKubeUtil(client, context.TODO()) @@ -133,7 +133,7 @@ func Test_CreateOrUpdateSecretData(t *testing.T) { "password": []byte("foobarbaz"), } - client := fake.NewSimpleClientset(secret) + client := fake.NewClientset(secret) t.Run("Change data in existing secret with merge", func(t *testing.T) { ku := NewKubeUtil(client, context.TODO()) diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index 558e67b70fcdf..27299495fd9be 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -29,6 +29,7 @@ const ( ) func testDataDir(tb testing.TB, testData string) (string, error) { + tb.Helper() res := tb.TempDir() _, err := exec.RunCommand("cp", exec.CmdOpts{}, "-r", "./testdata/"+testData, filepath.Join(res, "testdata")) if err != nil { diff --git a/util/localconfig/localconfig.go b/util/localconfig/localconfig.go index 2eb84e51e6c0d..221695354ec7f 100644 --- a/util/localconfig/localconfig.go +++ b/util/localconfig/localconfig.go @@ -8,6 +8,7 @@ import ( "github.com/golang-jwt/jwt/v4" + "github.com/argoproj/argo-cd/v2/util/config" configUtil "github.com/argoproj/argo-cd/v2/util/config" ) @@ -17,6 +18,7 @@ type LocalConfig struct { Contexts []ContextRef `json:"contexts"` Servers []Server `json:"servers"` Users []User `json:"users"` + PromptsEnabled bool `json:"prompts-enabled"` } // ContextRef is a reference to a Server and User for an API client @@ -306,3 +308,27 @@ func GetUsername(subject string) string { } return subject } + +func GetPromptsEnabled(useCLIOpts bool) bool { + if useCLIOpts { + forcePromptsEnabled := config.GetFlag("prompts-enabled", "") + + if forcePromptsEnabled != "" { + return forcePromptsEnabled == "true" + } + } + + defaultLocalConfigPath, err := DefaultLocalConfigPath() + if err != nil { + return false + } + + localConfigPath := config.GetFlag("config", defaultLocalConfigPath) + + localConfig, err := ReadLocalConfig(localConfigPath) + if localConfig == nil || err != nil { + return false + } + + return localConfig.PromptsEnabled +} diff --git a/util/localconfig/localconfig_test.go b/util/localconfig/localconfig_test.go index 3e8300faee8f1..ada30b865bd39 100644 --- a/util/localconfig/localconfig_test.go +++ b/util/localconfig/localconfig_test.go @@ -9,6 +9,8 @@ import ( "path/filepath" "testing" + "github.com/argoproj/argo-cd/v2/util/config" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" @@ -91,3 +93,112 @@ func TestFilePermission(t *testing.T) { }) } } + +const testConfig = `contexts: +- name: argocd1.example.com:443 + server: argocd1.example.com:443 + user: argocd1.example.com:443 +- name: argocd2.example.com:443 + server: argocd2.example.com:443 + user: argocd2.example.com:443 +- name: localhost:8080 + server: localhost:8080 + user: localhost:8080 +current-context: localhost:8080 +servers: +- server: argocd1.example.com:443 +- server: argocd2.example.com:443 +- plain-text: true + server: localhost:8080 +users: +- auth-token: vErrYS3c3tReFRe$hToken + name: argocd1.example.com:443 + refresh-token: vErrYS3c3tReFRe$hToken +- auth-token: vErrYS3c3tReFRe$hToken + name: argocd2.example.com:443 + refresh-token: vErrYS3c3tReFRe$hToken +- auth-token: vErrYS3c3tReFRe$hToken + name: localhost:8080` + +const testConfigFilePath = "./testdata/local.config" + +func loadOpts(t *testing.T, opts string) { + t.Helper() + t.Setenv("ARGOCD_OPTS", opts) + assert.NoError(t, config.LoadFlags()) +} + +func TestGetPromptsEnabled_useCLIOpts_false_localConfigPromptsEnabled_true(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig+"\nprompts-enabled: true"), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + loadOpts(t, "--config "+testConfigFilePath) + + assert.True(t, GetPromptsEnabled(false)) +} + +func TestGetPromptsEnabled_useCLIOpts_false_localConfigPromptsEnabled_false(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig+"\nprompts-enabled: false"), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + loadOpts(t, "--config "+testConfigFilePath) + + assert.False(t, GetPromptsEnabled(false)) +} + +func TestGetPromptsEnabled_useCLIOpts_true_forcePromptsEnabled_default(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig+"\nprompts-enabled: false"), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + loadOpts(t, "--config "+testConfigFilePath+" --prompts-enabled") + + assert.True(t, GetPromptsEnabled(true)) +} + +func TestGetPromptsEnabled_useCLIOpts_true_forcePromptsEnabled_true(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig+"\nprompts-enabled: false"), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + loadOpts(t, "--config "+testConfigFilePath+" --prompts-enabled=true") + + assert.True(t, GetPromptsEnabled(true)) +} + +func TestGetPromptsEnabled_useCLIOpts_true_forcePromptsEnabled_false(t *testing.T) { + // Write the test config file + err := os.WriteFile(testConfigFilePath, []byte(testConfig+"\nprompts-enabled: true"), os.ModePerm) + require.NoError(t, err) + + defer os.Remove(testConfigFilePath) + + err = os.Chmod(testConfigFilePath, 0o600) + require.NoError(t, err, "Could not change the file permission to 0600 %v", err) + + loadOpts(t, "--config "+testConfigFilePath+" --prompts-enabled=false") + + assert.False(t, GetPromptsEnabled(true)) +} diff --git a/util/localconfig/testdata/sample.local.config b/util/localconfig/testdata/sample.local.config new file mode 100644 index 0000000000000..71c320338d144 --- /dev/null +++ b/util/localconfig/testdata/sample.local.config @@ -0,0 +1,26 @@ +contexts: +- name: argocd1.example.com:443 + server: argocd1.example.com:443 + user: argocd1.example.com:443 +- name: argocd2.example.com:443 + server: argocd2.example.com:443 + user: argocd2.example.com:443 +- name: localhost:8080 + server: localhost:8080 + user: localhost:8080 +current-context: localhost:8080 +servers: +- server: argocd1.example.com:443 +- server: argocd2.example.com:443 +- plain-text: true + server: localhost:8080 +users: +- auth-token: vErrYS3c3tReFRe$hToken + name: argocd1.example.com:443 + refresh-token: vErrYS3c3tReFRe$hToken +- auth-token: vErrYS3c3tReFRe$hToken + name: argocd2.example.com:443 + refresh-token: vErrYS3c3tReFRe$hToken +- auth-token: vErrYS3c3tReFRe$hToken + name: localhost:8080 +prompts-enabled: true \ No newline at end of file diff --git a/util/lua/custom_actions_test.go b/util/lua/custom_actions_test.go index f71659de46f40..da635af3b02ac 100644 --- a/util/lua/custom_actions_test.go +++ b/util/lua/custom_actions_test.go @@ -110,8 +110,7 @@ func TestLuaResourceActionsScript(t *testing.T) { } require.NoError(t, err) dir := filepath.Dir(path) - // TODO: Change to path - yamlBytes, err := os.ReadFile(dir + "/action_test.yaml") + yamlBytes, err := os.ReadFile(filepath.Join(dir, "action_test.yaml")) require.NoError(t, err) var resourceTest ActionTestStructure err = yaml.Unmarshal(yamlBytes, &resourceTest) @@ -209,6 +208,7 @@ func TestLuaResourceActionsScript(t *testing.T) { // Handling backward compatibility. // The old-style actions return a single object in the expected output from testdata, so will wrap them in a list func getExpectedObjectList(t *testing.T, path string) *unstructured.UnstructuredList { + t.Helper() yamlBytes, err := os.ReadFile(path) errors.CheckError(err) unstructuredList := &unstructured.UnstructuredList{} diff --git a/util/lua/lua.go b/util/lua/lua.go index b255836b5434e..5183d018f84a4 100644 --- a/util/lua/lua.go +++ b/util/lua/lua.go @@ -24,13 +24,22 @@ import ( const ( incorrectReturnType = "expect %s output from Lua script, not %s" - incorrectInnerType = "expect %s inner type from Lua script, not %s" invalidHealthStatus = "Lua returned an invalid health status" healthScriptFile = "health.lua" actionScriptFile = "action.lua" actionDiscoveryScriptFile = "discovery.lua" ) +// ScriptDoesNotExistError is an error type for when a built-in script does not exist. +type ScriptDoesNotExistError struct { + // ScriptName is the name of the script that does not exist. + ScriptName string +} + +func (e ScriptDoesNotExistError) Error() string { + return fmt.Sprintf("built-in script %q does not exist", e.ScriptName) +} + type ResourceHealthOverrides map[string]appv1.ResourceOverride func (overrides ResourceHealthOverrides) GetResourceHealth(obj *unstructured.Unstructured) (*health.HealthStatus, error) { @@ -132,8 +141,9 @@ func (vm VM) ExecuteHealthLua(obj *unstructured.Unstructured, script string) (*h return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String()) } -// GetHealthScript attempts to read lua script from config and then filesystem for that resource -func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (string, bool, error) { +// GetHealthScript attempts to read lua script from config and then filesystem for that resource. If none exists, return +// an empty string. +func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (script string, useOpenLibs bool, err error) { // first, search the gvk as is in the ResourceOverrides key := GetConfigMapKey(obj.GroupVersionKind()) @@ -141,18 +151,24 @@ func (vm VM) GetHealthScript(obj *unstructured.Unstructured) (string, bool, erro return script.HealthLua, script.UseOpenLibs, nil } - // if not found as is, perhaps it matches wildcard entries in the configmap - wildcardKey := GetWildcardConfigMapKey(vm, obj.GroupVersionKind()) + // if not found as is, perhaps it matches a wildcard entry in the configmap + getWildcardHealthOverride, useOpenLibs := getWildcardHealthOverrideLua(vm.ResourceOverrides, obj.GroupVersionKind()) - if wildcardKey != "" { - if wildcardScript, ok := vm.ResourceOverrides[wildcardKey]; ok && wildcardScript.HealthLua != "" { - return wildcardScript.HealthLua, wildcardScript.UseOpenLibs, nil - } + if getWildcardHealthOverride != "" { + return getWildcardHealthOverride, useOpenLibs, nil } // if not found in the ResourceOverrides at all, search it as is in the built-in scripts // (as built-in scripts are files in folders, named after the GVK, currently there is no wildcard support for them) builtInScript, err := vm.getPredefinedLuaScripts(key, healthScriptFile) + if err != nil { + var doesNotExist *ScriptDoesNotExistError + if errors.As(err, &doesNotExist) { + // It's okay if no built-in health script exists. Just return an empty string and let the caller handle it. + return "", false, nil + } + return "", false, err + } // standard libraries will be enabled for all built-in scripts return builtInScript, true, err } @@ -382,7 +398,10 @@ func (vm VM) GetResourceActionDiscovery(obj *unstructured.Unstructured) ([]strin // Fetch predefined Lua scripts discoveryKey := fmt.Sprintf("%s/actions/", key) discoveryScript, err := vm.getPredefinedLuaScripts(discoveryKey, actionDiscoveryScriptFile) - if err != nil { + + // Ignore the error if the script does not exist. + var doesNotExistErr *ScriptDoesNotExistError + if err != nil && !errors.As(err, &doesNotExistErr) { return nil, fmt.Errorf("error while fetching predefined lua scripts: %w", err) } @@ -426,22 +445,25 @@ func GetConfigMapKey(gvk schema.GroupVersionKind) string { return fmt.Sprintf("%s/%s", gvk.Group, gvk.Kind) } -func GetWildcardConfigMapKey(vm VM, gvk schema.GroupVersionKind) string { +// getWildcardHealthOverrideLua returns the first encountered resource override which matches the wildcard and has a +// non-empty health script. Having multiple wildcards with non-empty health checks that can match the GVK is +// non-deterministic. +func getWildcardHealthOverrideLua(overrides map[string]appv1.ResourceOverride, gvk schema.GroupVersionKind) (string, bool) { gvkKeyToMatch := GetConfigMapKey(gvk) - for key := range vm.ResourceOverrides { - if glob.Match(key, gvkKeyToMatch) { - return key + for key, override := range overrides { + if glob.Match(key, gvkKeyToMatch) && override.HealthLua != "" { + return override.HealthLua, override.UseOpenLibs } } - return "" + return "", false } func (vm VM) getPredefinedLuaScripts(objKey string, scriptFile string) (string, error) { data, err := resource_customizations.Embedded.ReadFile(filepath.Join(objKey, scriptFile)) if err != nil { if os.IsNotExist(err) { - return "", nil + return "", &ScriptDoesNotExistError{ScriptName: objKey} } return "", err } diff --git a/util/lua/lua_test.go b/util/lua/lua_test.go index 4686d58ac128e..ae26448bedb15 100644 --- a/util/lua/lua_test.go +++ b/util/lua/lua_test.go @@ -266,7 +266,7 @@ func TestGetHealthScriptNoPredefined(t *testing.T) { vm := VM{} script, useOpenLibs, err := vm.GetHealthScript(testObj) require.NoError(t, err) - assert.True(t, useOpenLibs) + assert.False(t, useOpenLibs) assert.Equal(t, "", script) } @@ -283,7 +283,8 @@ func TestGetResourceActionNoPredefined(t *testing.T) { testObj := StrToUnstructured(objWithNoScriptJSON) vm := VM{} action, err := vm.GetResourceAction(testObj, "test") - require.NoError(t, err) + var expectedErr *ScriptDoesNotExistError + require.ErrorAs(t, err, &expectedErr) assert.Empty(t, action.ActionLua) } @@ -684,8 +685,7 @@ func TestExecuteNewStyleActionMixedOperationsFailure(t *testing.T) { testObj := StrToUnstructured(cronJobObjYaml) vm := VM{} _, err := vm.ExecuteResourceAction(testObj, createMixedOperationActionLuaFailing) - require.Error(t, err) - assert.Contains(t, err.Error(), "unsupported operation") + assert.ErrorContains(t, err, "unsupported operation") } func TestExecuteResourceActionNonTableReturn(t *testing.T) { @@ -787,6 +787,11 @@ return hs` const healthWildcardOverrideScript = ` hs = {} hs.status = "Healthy" + return hs` + + const healthWildcardOverrideScriptUnhealthy = ` + hs = {} + hs.status = "UnHealthy" return hs` getHealthOverride := func(openLibs bool) ResourceHealthOverrides { @@ -804,6 +809,21 @@ return hs` }, } + getMultipleWildcardHealthOverrides := ResourceHealthOverrides{ + "*.aws.crossplane.io/*": appv1.ResourceOverride{ + HealthLua: "", + }, + "*.aws*": appv1.ResourceOverride{ + HealthLua: healthWildcardOverrideScriptUnhealthy, + }, + } + + getBaseWildcardHealthOverrides := ResourceHealthOverrides{ + "*/*": appv1.ResourceOverride{ + HealthLua: "", + }, + } + t.Run("Enable Lua standard lib", func(t *testing.T) { testObj := StrToUnstructured(testSA) overrides := getHealthOverride(true) @@ -837,6 +857,23 @@ return hs` assert.Equal(t, expectedStatus, status) }) + t.Run("Get resource health for wildcard override with non-empty health.lua", func(t *testing.T) { + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) + overrides := getMultipleWildcardHealthOverrides + status, err := overrides.GetResourceHealth(testObj) + require.NoError(t, err) + expectedStatus := &health.HealthStatus{Status: "Unknown", Message: "Lua returned an invalid health status"} + assert.Equal(t, expectedStatus, status) + }) + + t.Run("Get resource health for */* override with empty health.lua", func(t *testing.T) { + testObj := StrToUnstructured(ec2AWSCrossplaneObjJson) + overrides := getBaseWildcardHealthOverrides + status, err := overrides.GetResourceHealth(testObj) + require.NoError(t, err) + assert.Nil(t, status) + }) + t.Run("Resource health for wildcard override not found", func(t *testing.T) { testObj := StrToUnstructured(testSA) overrides := getWildcardHealthOverride diff --git a/util/lua/oslib_safe.go b/util/lua/oslib_safe.go index 1b84a18b61905..2d5a94e9463f2 100644 --- a/util/lua/oslib_safe.go +++ b/util/lua/oslib_safe.go @@ -6,7 +6,7 @@ package lua // github.com/yuin/gopher-lua. import ( - "fmt" + "strconv" "strings" "time" @@ -116,7 +116,7 @@ func strftime(t time.Time, cfmt string) string { } else { switch c { case 'w': - sc.AppendString(fmt.Sprint(int(t.Weekday()))) + sc.AppendString(strconv.Itoa(int(t.Weekday()))) default: sc.AppendChar('%') sc.AppendChar(c) diff --git a/util/manifeststream/stream_test.go b/util/manifeststream/stream_test.go index cc3e5152a7cb7..cbb32ed5e9fd5 100644 --- a/util/manifeststream/stream_test.go +++ b/util/manifeststream/stream_test.go @@ -122,5 +122,6 @@ func TestManifestStream(t *testing.T) { } func getTestDataDir(t *testing.T) string { + t.Helper() return filepath.Join(test.GetTestDir(t), "testdata") } diff --git a/util/notification/settings/settings_test.go b/util/notification/settings/settings_test.go index c80a50142ceaa..8c3a8c5bf9ddb 100644 --- a/util/notification/settings/settings_test.go +++ b/util/notification/settings/settings_test.go @@ -44,7 +44,7 @@ func TestInitGetVars(t *testing.T) { "notification-secret": []byte("secret-value"), }, } - kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ + kubeclientset := fake.NewClientset(&corev1.ConfigMap{ ObjectMeta: v1.ObjectMeta{ Namespace: testNamespace, Name: "argocd-notifications-cm", diff --git a/util/oidc/oidc.go b/util/oidc/oidc.go index 5708532061d6a..2f01dc167e3d4 100644 --- a/util/oidc/oidc.go +++ b/util/oidc/oidc.go @@ -590,7 +590,7 @@ func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoP } url := issuerURL + userInfoPath - request, err := http.NewRequest("GET", url, nil) + request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { err = fmt.Errorf("failed creating new http request: %w", err) return claims, false, err diff --git a/util/oidc/oidc_test.go b/util/oidc/oidc_test.go index 8332acaf98885..40c606dcd9671 100644 --- a/util/oidc/oidc_test.go +++ b/util/oidc/oidc_test.go @@ -79,7 +79,7 @@ func TestIDTokenClaims(t *testing.T) { values, err := url.ParseQuery(authCodeURL.RawQuery) require.NoError(t, err) - assert.Equal(t, "{\"id_token\":{\"groups\":{\"essential\":true}}}", values.Get("claims")) + assert.JSONEq(t, "{\"id_token\":{\"groups\":{\"essential\":true}}}", values.Get("claims")) } type fakeProvider struct{} diff --git a/util/password/password_test.go b/util/password/password_test.go index c4d222e719f22..bbdf1ebb51fb1 100644 --- a/util/password/password_test.go +++ b/util/password/password_test.go @@ -5,6 +5,7 @@ import ( ) func testPasswordHasher(t *testing.T, h PasswordHasher) { + t.Helper() // Use the default work factor const ( defaultPassword = "Hello, world!" diff --git a/util/rbac/rbac_norace_test.go b/util/rbac/rbac_norace_test.go index 41503746cd540..80314d04f3420 100644 --- a/util/rbac/rbac_norace_test.go +++ b/util/rbac/rbac_norace_test.go @@ -26,7 +26,7 @@ func TestPolicyInformer(t *testing.T) { cm := fakeConfigMap() cm.Data[ConfigMapPolicyCSVKey] = "p, admin, applications, delete, */*, allow" - kubeclientset := fake.NewSimpleClientset(cm) + kubeclientset := fake.NewClientset(cm) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) ctx := context.Background() @@ -58,7 +58,7 @@ func TestResourceActionWildcards(t *testing.T) { // !race: // Same as TestPolicyInformer - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) + kubeclientset := fake.NewClientset(fakeConfigMap()) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) policy := ` p, alice, *, get, foo/obj, allow diff --git a/util/rbac/rbac_test.go b/util/rbac/rbac_test.go index f0843952cd2e9..8bf1b780af6b4 100644 --- a/util/rbac/rbac_test.go +++ b/util/rbac/rbac_test.go @@ -106,7 +106,7 @@ func TestPolicyCSV(t *testing.T) { // TestBuiltinPolicyEnforcer tests the builtin policy rules func TestBuiltinPolicyEnforcer(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) @@ -142,7 +142,7 @@ func TestBuiltinPolicyEnforcer(t *testing.T) { // TestProjectIsolationEnforcement verifies the ability to create Project specific policies func TestProjectIsolationEnforcement(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) + kubeclientset := fake.NewClientset(fakeConfigMap()) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) policy := ` p, role:foo-admin, *, *, foo/*, allow @@ -162,7 +162,7 @@ g, bob, role:bar-admin // TestProjectReadOnly verifies the ability to have a read only role in a Project func TestProjectReadOnly(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) + kubeclientset := fake.NewClientset(fakeConfigMap()) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) policy := ` p, role:foo-readonly, *, get, foo/*, allow @@ -178,7 +178,7 @@ g, alice, role:foo-readonly // TestDefaultRole tests the ability to set a default role func TestDefaultRole(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) @@ -191,7 +191,7 @@ func TestDefaultRole(t *testing.T) { // TestURLAsObjectName tests the ability to have a URL as an object name func TestURLAsObjectName(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) policy := ` @@ -209,7 +209,7 @@ p, cathy, repositories, *, foo/*, allow } func TestEnableDisableEnforce(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) + kubeclientset := fake.NewClientset(fakeConfigMap()) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) policy := ` p, alice, *, get, foo/obj, allow @@ -237,7 +237,7 @@ p, mike, *, get, foo/obj, deny } func TestUpdatePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset(fakeConfigMap()) + kubeclientset := fake.NewClientset(fakeConfigMap()) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) _ = enf.SetUserPolicy("p, alice, *, get, foo/obj, allow") @@ -267,14 +267,14 @@ func TestUpdatePolicy(t *testing.T) { func TestNoPolicy(t *testing.T) { cm := fakeConfigMap() - kubeclientset := fake.NewSimpleClientset(cm) + kubeclientset := fake.NewClientset(cm) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) assert.False(t, enf.Enforce("admin", "applications", "delete", "foo/bar")) } // TestClaimsEnforcerFunc tests func TestClaimsEnforcerFunc(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) claims := jwt.RegisteredClaims{ Subject: "foo", @@ -289,7 +289,7 @@ func TestClaimsEnforcerFunc(t *testing.T) { // TestDefaultRoleWithRuntimePolicy tests the ability for a default role to still take affect when // enforcing a runtime policy func TestDefaultRoleWithRuntimePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) runtimePolicy := assets.BuiltinPolicyCSV @@ -301,7 +301,7 @@ func TestDefaultRoleWithRuntimePolicy(t *testing.T) { // TestClaimsEnforcerFuncWithRuntimePolicy tests the ability for claims enforcer function to still // take effect when enforcing a runtime policy func TestClaimsEnforcerFuncWithRuntimePolicy(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) runtimePolicy := assets.BuiltinPolicyCSV @@ -318,7 +318,7 @@ func TestClaimsEnforcerFuncWithRuntimePolicy(t *testing.T) { // TestInvalidRuntimePolicy tests when an invalid policy is supplied, it falls back to normal enforcement func TestInvalidRuntimePolicy(t *testing.T) { cm := fakeConfigMap() - kubeclientset := fake.NewSimpleClientset(cm) + kubeclientset := fake.NewClientset(cm) enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) @@ -351,7 +351,7 @@ func TestValidatePolicy(t *testing.T) { // TestEnforceErrorMessage ensures we give descriptive error message func TestEnforceErrorMessage(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) err := enf.syncUpdate(fakeConfigMap(), noOpUpdate) require.NoError(t, err) @@ -392,7 +392,7 @@ func TestEnforceErrorMessage(t *testing.T) { } func TestDefaultGlobMatchMode(t *testing.T) { - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(fakeConfigMap(), noOpUpdate)) policy := ` @@ -407,7 +407,7 @@ p, alice, clusters, get, "https://github.com/*/*.git", allow func TestGlobMatchMode(t *testing.T) { cm := fakeConfigMap() cm.Data[ConfigMapMatchModeKey] = GlobMatchMode - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(cm, noOpUpdate)) policy := ` @@ -422,7 +422,7 @@ p, alice, clusters, get, "https://github.com/*/*.git", allow func TestRegexMatchMode(t *testing.T) { cm := fakeConfigMap() cm.Data[ConfigMapMatchModeKey] = RegexMatchMode - kubeclientset := fake.NewSimpleClientset() + kubeclientset := fake.NewClientset() enf := NewEnforcer(kubeclientset, fakeNamespace, fakeConfigMapName, nil) require.NoError(t, enf.syncUpdate(cm, noOpUpdate)) policy := ` diff --git a/util/security/jwt_test.go b/util/security/jwt_test.go index fb25c4e01ed00..f8131259c1138 100644 --- a/util/security/jwt_test.go +++ b/util/security/jwt_test.go @@ -13,6 +13,7 @@ import ( func Test_UnverifiedHasAudClaim(t *testing.T) { tokenForAud := func(t *testing.T, aud jwt.ClaimStrings) string { + t.Helper() claims := jwt.RegisteredClaims{Audience: aud, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24))} token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims) key, err := jwt.ParseRSAPrivateKeyFromPEM(utiltest.PrivateKey) diff --git a/util/session/sessionmanager_test.go b/util/session/sessionmanager_test.go index 7a3d5a65f5f5a..73d8fdb8eaecb 100644 --- a/util/session/sessionmanager_test.go +++ b/util/session/sessionmanager_test.go @@ -52,7 +52,7 @@ func getKubeClient(pass string, enabled bool, capabilities ...settings.AccountCa capabilitiesStr = append(capabilitiesStr, string(capabilities[i])) } - return fake.NewSimpleClientset(&corev1.ConfigMap{ + return fake.NewClientset(&corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: "argocd", @@ -101,7 +101,7 @@ func TestSessionManager_AdminToken(t *testing.T) { mapClaims := *(claims.(*jwt.MapClaims)) subject := mapClaims["sub"].(string) if subject != "admin" { - t.Errorf("Token claim subject \"%s\" does not match expected subject \"%s\".", subject, "admin") + t.Errorf("Token claim subject %q does not match expected subject %q.", subject, "admin") } } @@ -160,8 +160,7 @@ func TestSessionManager_AdminToken_Deactivated(t *testing.T) { } _, _, err = mgr.Parse(token) - require.Error(t, err) - assert.Contains(t, err.Error(), "account admin is disabled") + assert.ErrorContains(t, err, "account admin is disabled") } func TestSessionManager_AdminToken_LoginCapabilityDisabled(t *testing.T) { @@ -174,8 +173,7 @@ func TestSessionManager_AdminToken_LoginCapabilityDisabled(t *testing.T) { } _, _, err = mgr.Parse(token) - require.Error(t, err) - assert.Contains(t, err.Error(), "account admin does not have 'apiKey' capability") + assert.ErrorContains(t, err, "account admin does not have 'apiKey' capability") } func TestSessionManager_ProjectToken(t *testing.T) { @@ -218,9 +216,7 @@ func TestSessionManager_ProjectToken(t *testing.T) { require.NoError(t, err) _, _, err = mgr.Parse(jwtToken) - require.Error(t, err) - - assert.Contains(t, err.Error(), "does not exist in project 'default'") + assert.ErrorContains(t, err, "does not exist in project 'default'") }) } @@ -255,9 +251,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/text") _, err := w.Write([]byte("Ok")) - if err != nil { - t.Fatalf("error writing response: %s", err) - } + require.NoError(t, err, "error writing response: %s", err) } } type testCase struct { @@ -277,7 +271,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: true, verifiedClaims: &claimsMock{}, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, { @@ -286,7 +280,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: false, verifiedClaims: nil, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, { @@ -295,7 +289,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: false, verifiedClaims: &claimsMock{}, verifyTokenErr: nil, - expectedStatusCode: 400, + expectedStatusCode: http.StatusBadRequest, expectedResponseBody: nil, }, { @@ -304,7 +298,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: true, verifiedClaims: &claimsMock{}, verifyTokenErr: stderrors.New("token error"), - expectedStatusCode: 401, + expectedStatusCode: http.StatusUnauthorized, expectedResponseBody: nil, }, { @@ -313,7 +307,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: true, verifiedClaims: nil, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, } @@ -330,9 +324,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { ts := httptest.NewServer(WithAuthMiddleware(tc.authDisabled, tm, mux)) defer ts.Close() req, err := http.NewRequest(http.MethodGet, ts.URL, nil) - if err != nil { - t.Fatalf("error creating request: %s", err) - } + require.NoErrorf(t, err, "error creating request: %s", err) if tc.cookieHeader { req.Header.Add("Cookie", "argocd.token=123456") } @@ -482,8 +474,8 @@ func TestCacheValueGetters(t *testing.T) { }) t.Run("Greater than allowed in environment overrides", func(t *testing.T) { - t.Setenv(envLoginMaxFailCount, fmt.Sprintf("%d", math.MaxInt32+1)) - t.Setenv(envLoginMaxCacheSize, fmt.Sprintf("%d", math.MaxInt32+1)) + t.Setenv(envLoginMaxFailCount, strconv.Itoa(math.MaxInt32+1)) + t.Setenv(envLoginMaxCacheSize, strconv.Itoa(math.MaxInt32+1)) mlf := getMaxLoginFailures() assert.Equal(t, defaultMaxLoginFailures, mlf) @@ -538,8 +530,7 @@ func TestMaxUsernameLength(t *testing.T) { settingsMgr := settings.NewSettingsManager(context.Background(), getKubeClient("password", true), "argocd") mgr := newSessionManager(settingsMgr, getProjLister(), NewUserStateStorage(nil)) err := mgr.VerifyUsernamePassword(username, "password") - require.Error(t, err) - assert.Contains(t, err.Error(), fmt.Sprintf(usernameTooLongError, maxUsernameLength)) + assert.ErrorContains(t, err, fmt.Sprintf(usernameTooLongError, maxUsernameLength)) } func TestMaxCacheSize(t *testing.T) { @@ -586,7 +577,7 @@ func getKubeClientWithConfig(config map[string]string, secretConfig map[string][ mergedSecretConfig[key] = value } - return fake.NewSimpleClientset(&corev1.ConfigMap{ + return fake.NewClientset(&corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd-cm", Namespace: "argocd", diff --git a/util/session/state.go b/util/session/state.go index b4117c0d1733f..db8eda5020ee3 100644 --- a/util/session/state.go +++ b/util/session/state.go @@ -125,6 +125,10 @@ func (storage *userStateStorage) IsTokenRevoked(id string) bool { return storage.revokedTokens[id] } +func (storage *userStateStorage) GetLockObject() *sync.RWMutex { + return &storage.lock +} + type UserStateStorage interface { Init(ctx context.Context) // GetLoginAttempts return number of concurrent login attempts @@ -135,4 +139,6 @@ type UserStateStorage interface { RevokeToken(ctx context.Context, id string, expiringAt time.Duration) error // IsTokenRevoked checks if given token is revoked IsTokenRevoked(id string) bool + // GetLockObject returns a lock used by the storage + GetLockObject() *sync.RWMutex } diff --git a/util/settings/accounts_test.go b/util/settings/accounts_test.go index 1415ce226de3d..2ab477ba6a963 100644 --- a/util/settings/accounts_test.go +++ b/util/settings/accounts_test.go @@ -164,7 +164,7 @@ func TestAddAccount_AccountAdded(t *testing.T) { assert.Equal(t, "hash", string(secret.Data["accounts.test.password"])) assert.Equal(t, mTime.Format(time.RFC3339), string(secret.Data["accounts.test.passwordMtime"])) - assert.Equal(t, `[{"id":"123","iat":0}]`, string(secret.Data["accounts.test.tokens"])) + assert.JSONEq(t, `[{"id":"123","iat":0}]`, string(secret.Data["accounts.test.tokens"])) } func TestAddAccount_AlreadyExists(t *testing.T) { @@ -204,7 +204,7 @@ func TestUpdateAccount_SuccessfullyUpdated(t *testing.T) { assert.Equal(t, "hash", string(secret.Data["accounts.test.password"])) assert.Equal(t, mTime.Format(time.RFC3339), string(secret.Data["accounts.test.passwordMtime"])) - assert.Equal(t, `[{"id":"123","iat":0}]`, string(secret.Data["accounts.test.tokens"])) + assert.JSONEq(t, `[{"id":"123","iat":0}]`, string(secret.Data["accounts.test.tokens"])) } func TestUpdateAccount_UpdateAdminPassword(t *testing.T) { diff --git a/util/settings/settings.go b/util/settings/settings.go index 7d192d9cb9461..3938fbca96c62 100644 --- a/util/settings/settings.go +++ b/util/settings/settings.go @@ -123,9 +123,9 @@ type ArgoCDSettings struct { OIDCTLSInsecureSkipVerify bool `json:"oidcTLSInsecureSkipVerify"` // AppsInAnyNamespaceEnabled indicates whether applications are allowed to be created in any namespace AppsInAnyNamespaceEnabled bool `json:"appsInAnyNamespaceEnabled"` - // ExtensionConfig configurations related to ArgoCD proxy extensions. The value - // is a yaml string defined in extension.ExtensionConfigs struct. - ExtensionConfig string `json:"extensionConfig,omitempty"` + // ExtensionConfig configurations related to ArgoCD proxy extensions. The keys are the extension name. + // The value is a yaml string defined in extension.ExtensionConfigs struct. + ExtensionConfig map[string]string `json:"extensionConfig,omitempty"` // ImpersonationEnabled indicates whether Application sync privileges can be decoupled from control plane // privileges using impersonation ImpersonationEnabled bool `json:"impersonationEnabled"` @@ -261,9 +261,10 @@ var ( } return nil, nil } - ByProjectClusterIndexer = "byProjectCluster" - ByProjectRepoIndexer = "byProjectRepo" - byProjectIndexerFunc = func(secretType string) func(obj interface{}) ([]string, error) { + ByProjectClusterIndexer = "byProjectCluster" + ByProjectRepoIndexer = "byProjectRepo" + ByProjectRepoWriteIndexer = "byProjectRepoWrite" + byProjectIndexerFunc = func(secretType string) func(obj interface{}) ([]string, error) { return func(obj interface{}) ([]string, error) { s, ok := obj.(*apiv1.Secret) if !ok { @@ -451,6 +452,8 @@ const ( settingsApplicationInstanceLabelKey = "application.instanceLabelKey" // settingsResourceTrackingMethodKey is the key to configure tracking method for application resources settingsResourceTrackingMethodKey = "application.resourceTrackingMethod" + // settingsInstallationID holds the key for the instance installation ID + settingsInstallationID = "installationID" // resourcesCustomizationsKey is the key to the map of resource overrides resourceCustomizationsKey = "resource.customizations" // resourceExclusions is the key to the list of excluded resources @@ -459,6 +462,8 @@ const ( resourceInclusionsKey = "resource.inclusions" // resourceIgnoreResourceUpdatesEnabledKey is the key to a boolean determining whether the resourceIgnoreUpdates feature is enabled resourceIgnoreResourceUpdatesEnabledKey = "resource.ignoreResourceUpdatesEnabled" + // resourceSensitiveAnnotationsKey is the key to list of annotations to mask in secret resource + resourceSensitiveAnnotationsKey = "resource.sensitive.mask.annotations" // resourceCustomLabelKey is the key to a custom label to show in node info, if present resourceCustomLabelsKey = "resource.customLabels" // resourceIncludeEventLabelKeys is the key to labels to be added onto Application k8s events if present on an Application or it's AppProject. Supports wildcard. @@ -533,8 +538,11 @@ const ( ) const ( - // default max webhook payload size is 1GB - defaultMaxWebhookPayloadSize = int64(1) * 1024 * 1024 * 1024 + // default max webhook payload size is 50MB + defaultMaxWebhookPayloadSize = int64(50) * 1024 * 1024 + + // application sync with impersonation feature is disabled by default. + defaultImpersonationEnabledFlag = false ) var sourceTypeToEnableGenerationKey = map[v1alpha1.ApplicationSourceType]string{ @@ -792,6 +800,14 @@ func (mgr *SettingsManager) GetTrackingMethod() (string, error) { return argoCDCM.Data[settingsResourceTrackingMethodKey], nil } +func (mgr *SettingsManager) GetInstallationID() (string, error) { + argoCDCM, err := mgr.getConfigMap() + if err != nil { + return "", err + } + return argoCDCM.Data[settingsInstallationID], nil +} + func (mgr *SettingsManager) GetPasswordPattern() (string, error) { argoCDCM, err := mgr.getConfigMap() if err != nil { @@ -906,7 +922,7 @@ func (mgr *SettingsManager) GetIsIgnoreResourceUpdatesEnabled() (bool, error) { } if argoCDCM.Data[resourceIgnoreResourceUpdatesEnabledKey] == "" { - return false, nil + return true, nil } return strconv.ParseBool(argoCDCM.Data[resourceIgnoreResourceUpdatesEnabledKey]) @@ -1324,6 +1340,10 @@ func (mgr *SettingsManager) GetSettings() (*ArgoCDSettings, error) { if err != nil { return nil, err } + // SecretNamespaceLister lists all Secrets in the indexer for a given namespace. + // Objects returned by the lister must be treated as read-only. + // To allow us to modify the secrets, make a copy + secrets = util.SecretCopy(secrets) var settings ArgoCDSettings var errs []error updateSettingsFromConfigMap(&settings, argoCDCM) @@ -1365,11 +1385,12 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error { }, } indexers := cache.Indexers{ - cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, - ByClusterURLIndexer: byClusterURLIndexerFunc, - ByClusterNameIndexer: byClusterNameIndexerFunc, - ByProjectClusterIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeCluster), - ByProjectRepoIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepository), + cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, + ByClusterURLIndexer: byClusterURLIndexerFunc, + ByClusterNameIndexer: byClusterNameIndexerFunc, + ByProjectClusterIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeCluster), + ByProjectRepoIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepository), + ByProjectRepoWriteIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepositoryWrite), } cmInformer := v1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers, tweakConfigMap) secretsInformer := v1.NewSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, indexers) @@ -1524,10 +1545,21 @@ func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *apiv1.Confi } settings.TrackingMethod = argoCDCM.Data[settingsResourceTrackingMethodKey] settings.OIDCTLSInsecureSkipVerify = argoCDCM.Data[oidcTLSInsecureSkipVerifyKey] == "true" - settings.ExtensionConfig = argoCDCM.Data[extensionConfig] + settings.ExtensionConfig = getExtensionConfigs(argoCDCM.Data) settings.ImpersonationEnabled = argoCDCM.Data[impersonationEnabledKey] == "true" } +func getExtensionConfigs(cmData map[string]string) map[string]string { + result := make(map[string]string) + for k, v := range cmData { + if strings.HasPrefix(k, extensionConfig) { + extName := strings.TrimPrefix(strings.TrimPrefix(k, extensionConfig), ".") + result[extName] = v + } + } + return result +} + // validateExternalURL ensures the external URL that is set on the configmap is valid func validateExternalURL(u string) error { if u == "" { @@ -2317,6 +2349,28 @@ func (mgr *SettingsManager) GetExcludeEventLabelKeys() []string { return labelKeys } +func (mgr *SettingsManager) GetSensitiveAnnotations() map[string]bool { + annotationKeys := make(map[string]bool) + + argoCDCM, err := mgr.getConfigMap() + if err != nil { + log.Error(fmt.Errorf("failed getting configmap: %w", err)) + return annotationKeys + } + + value, ok := argoCDCM.Data[resourceSensitiveAnnotationsKey] + if !ok || value == "" { + return annotationKeys + } + + value = strings.ReplaceAll(value, " ", "") + keys := strings.Split(value, ",") + for _, k := range keys { + annotationKeys[k] = true + } + return annotationKeys +} + func (mgr *SettingsManager) GetMaxWebhookPayloadSize() int64 { argoCDCM, err := mgr.getConfigMap() if err != nil { @@ -2336,11 +2390,11 @@ func (mgr *SettingsManager) GetMaxWebhookPayloadSize() int64 { return maxPayloadSizeMB * 1024 * 1024 } -// GetIsImpersonationEnabled returns true if application sync with impersonation feature is enabled in argocd-cm configmap -func (mgr *SettingsManager) IsImpersonationEnabled() bool { +// IsImpersonationEnabled returns true if application sync with impersonation feature is enabled in argocd-cm configmap +func (mgr *SettingsManager) IsImpersonationEnabled() (bool, error) { cm, err := mgr.getConfigMap() if err != nil { - return false + return defaultImpersonationEnabledFlag, fmt.Errorf("error checking %s property in configmap: %w", impersonationEnabledKey, err) } - return cm.Data[impersonationEnabledKey] == "true" + return cm.Data[impersonationEnabledKey] == "true", nil } diff --git a/util/settings/settings_test.go b/util/settings/settings_test.go index 94d5eeccf8021..7159c6a5a2c7e 100644 --- a/util/settings/settings_test.go +++ b/util/settings/settings_test.go @@ -50,7 +50,7 @@ func fixtures(data map[string]string, opts ...func(secret *v1.Secret)) (*fake.Cl for i := range opts { opts[i](secret) } - kubeClient := fake.NewSimpleClientset(cm, secret) + kubeClient := fake.NewClientset(cm, secret) settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") return kubeClient, settingsManager @@ -75,6 +75,52 @@ func TestGetRepositories(t *testing.T) { assert.Equal(t, []Repository{{URL: "http://foo"}}, filter) } +func TestGetExtensionConfigs(t *testing.T) { + type cases struct { + name string + input map[string]string + expected map[string]string + expectedLen int + } + + testCases := []cases{ + { + name: "will return main config successfully", + expectedLen: 1, + input: map[string]string{ + extensionConfig: "test", + }, + expected: map[string]string{ + "": "test", + }, + }, + { + name: "will return main and additional config successfully", + expectedLen: 2, + input: map[string]string{ + extensionConfig: "main config", + fmt.Sprintf("%s.anotherExtension", extensionConfig): "another config", + }, + expected: map[string]string{ + "": "main config", + "anotherExtension": "another config", + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + // When + output := getExtensionConfigs(tc.input) + + // Then + assert.Len(t, output, tc.expectedLen) + assert.Equal(t, tc.expected, output) + }) + } +} + func TestSaveRepositories(t *testing.T) { kubeClient, settingsManager := fixtures(nil) err := settingsManager.SaveRepositories([]Repository{{URL: "http://foo"}}) @@ -89,7 +135,7 @@ func TestSaveRepositories(t *testing.T) { } func TestSaveRepositoriesNoConfigMap(t *testing.T) { - kubeClient := fake.NewSimpleClientset() + kubeClient := fake.NewClientset() settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") err := settingsManager.SaveRepositories([]Repository{{URL: "http://foo"}}) @@ -152,7 +198,7 @@ func TestInClusterServerAddressEnabled(t *testing.T) { } func TestInClusterServerAddressEnabledByDefault(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -200,16 +246,23 @@ func TestGetServerRBACLogEnforceEnableKeyDefaultFalse(t *testing.T) { } func TestGetIsIgnoreResourceUpdatesEnabled(t *testing.T) { - _, settingsManager := fixtures(map[string]string{ + _, settingsManager := fixtures(nil) + ignoreResourceUpdatesEnabled, err := settingsManager.GetIsIgnoreResourceUpdatesEnabled() + require.NoError(t, err) + assert.True(t, ignoreResourceUpdatesEnabled) + + _, settingsManager = fixtures(map[string]string{ "resource.ignoreResourceUpdatesEnabled": "true", }) - ignoreResourceUpdatesEnabled, err := settingsManager.GetIsIgnoreResourceUpdatesEnabled() + ignoreResourceUpdatesEnabled, err = settingsManager.GetIsIgnoreResourceUpdatesEnabled() require.NoError(t, err) assert.True(t, ignoreResourceUpdatesEnabled) } -func TestGetIsIgnoreResourceUpdatesEnabledDefaultFalse(t *testing.T) { - _, settingsManager := fixtures(nil) +func TestGetIsIgnoreResourceUpdatesEnabledFalse(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + "resource.ignoreResourceUpdatesEnabled": "false", + }) ignoreResourceUpdatesEnabled, err := settingsManager.GetIsIgnoreResourceUpdatesEnabled() require.NoError(t, err) assert.False(t, ignoreResourceUpdatesEnabled) @@ -867,7 +920,7 @@ func TestSettingsManager_GetHelp(t *testing.T) { func TestSettingsManager_GetSettings(t *testing.T) { t.Run("UserSessionDurationNotProvided", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -897,7 +950,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { assert.Equal(t, time.Hour*24, s.UserSessionDuration) }) t.Run("UserSessionDurationInvalidFormat", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -929,7 +982,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { assert.Equal(t, time.Hour*24, s.UserSessionDuration) }) t.Run("UserSessionDurationProvided", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -963,7 +1016,7 @@ func TestSettingsManager_GetSettings(t *testing.T) { } func TestGetOIDCConfig(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1043,7 +1096,7 @@ func Test_validateExternalURL(t *testing.T) { } func TestGetOIDCSecretTrim(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1089,7 +1142,7 @@ func getCNFromCertificate(cert *tls.Certificate) string { func Test_GetTLSConfiguration(t *testing.T) { t.Run("Valid external TLS secret with success", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1135,7 +1188,7 @@ func Test_GetTLSConfiguration(t *testing.T) { }) t.Run("Valid external TLS secret overrides argocd-secret", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1182,7 +1235,7 @@ func Test_GetTLSConfiguration(t *testing.T) { assert.Contains(t, getCNFromCertificate(settings.Certificate), "localhost") }) t.Run("Invalid external TLS secret", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1221,12 +1274,11 @@ func Test_GetTLSConfiguration(t *testing.T) { ) settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() - require.Error(t, err) - assert.Contains(t, err.Error(), "could not read from secret") + require.ErrorContains(t, err, "could not read from secret") assert.NotNil(t, settings) }) t.Run("No external TLS secret", func(t *testing.T) { - kubeClient := fake.NewSimpleClientset( + kubeClient := fake.NewClientset( &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDConfigMapName, @@ -1333,7 +1385,7 @@ requestedIDTokenClaims: {"groups": {"essential": true}}`, "webhook.github.secret": []byte("mywebhooksecret"), }, } - kubeClient := fake.NewSimpleClientset(cm, secret, argocdSecret) + kubeClient := fake.NewClientset(cm, secret, argocdSecret) settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") settings, err := settingsManager.GetSettings() @@ -1391,7 +1443,7 @@ func TestGetEnableManifestGeneration(t *testing.T) { }, } - kubeClient := fake.NewSimpleClientset(cm, argocdSecret) + kubeClient := fake.NewClientset(cm, argocdSecret) settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") enableManifestGeneration, err := settingsManager.GetEnabledSourceTypes() @@ -1460,7 +1512,7 @@ func TestGetHelmSettings(t *testing.T) { "clientSecret": []byte("deadbeef"), }, } - kubeClient := fake.NewSimpleClientset(cm, secret, argocdSecret) + kubeClient := fake.NewClientset(cm, secret, argocdSecret) settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") helmSettings, err := settingsManager.GetHelmSettings() @@ -1725,3 +1777,80 @@ func TestRedirectAdditionalURLs(t *testing.T) { }) } } + +func TestIsImpersonationEnabled(t *testing.T) { + // When there is no argocd-cm itself, + // Then IsImpersonationEnabled() must return false (default value) and an error with appropriate error message. + kubeClient := fake.NewClientset() + settingsManager := NewSettingsManager(context.Background(), kubeClient, "default") + featureFlag, err := settingsManager.IsImpersonationEnabled() + require.False(t, featureFlag, + "with no argocd-cm config map, IsImpersonationEnabled() must return return false (default value)") + require.ErrorContains(t, err, "configmap \"argocd-cm\" not found", + "with no argocd-cm config map, IsImpersonationEnabled() must return an error") + + // When there is no impersonation feature flag present in the argocd-cm, + // Then IsImpersonationEnabled() must return false (default value) and nil error. + _, settingsManager = fixtures(map[string]string{}) + featureFlag, err = settingsManager.IsImpersonationEnabled() + require.False(t, featureFlag, + "with empty argocd-cm config map, IsImpersonationEnabled() must return false (default value)") + require.NoError(t, err, + "with empty argocd-cm config map, IsImpersonationEnabled() must not return any error") + + // When user disables the feature explicitly, + // Then IsImpersonationEnabled() must return false and nil error. + _, settingsManager = fixtures(map[string]string{ + "application.sync.impersonation.enabled": "false", + }) + featureFlag, err = settingsManager.IsImpersonationEnabled() + require.False(t, featureFlag, + "when user enables the flag in argocd-cm config map, IsImpersonationEnabled() must return user set value") + require.NoError(t, err, + "when user enables the flag in argocd-cm config map, IsImpersonationEnabled() must not return any error") + + // When user enables the feature explicitly, + // Then IsImpersonationEnabled() must return true and nil error. + _, settingsManager = fixtures(map[string]string{ + "application.sync.impersonation.enabled": "true", + }) + featureFlag, err = settingsManager.IsImpersonationEnabled() + require.True(t, featureFlag, + "when user enables the flag in argocd-cm config map, IsImpersonationEnabled() must return user set value") + require.NoError(t, err, + "when user enables the flag in argocd-cm config map, IsImpersonationEnabled() must not return any error") +} + +func TestSettingsManager_GetHideSecretAnnotations(t *testing.T) { + tests := []struct { + name string + input string + output map[string]bool + }{ + { + name: "Empty input", + input: "", + output: map[string]bool{}, + }, + { + name: "Comma separated data", + input: "example.com/token-secret.value,token,key", + output: map[string]bool{"example.com/token-secret.value": true, "token": true, "key": true}, + }, + { + name: "Comma separated data with space", + input: "example.com/token-secret.value, token, key", + output: map[string]bool{"example.com/token-secret.value": true, "token": true, "key": true}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, settingsManager := fixtures(map[string]string{ + resourceSensitiveAnnotationsKey: tt.input, + }) + keys := settingsManager.GetSensitiveAnnotations() + assert.Equal(t, len(tt.output), len(keys)) + assert.Equal(t, tt.output, keys) + }) + } +} diff --git a/util/swagger/swagger_test.go b/util/swagger/swagger_test.go index b615e5ebe190a..4c6e26c739f63 100644 --- a/util/swagger/swagger_test.go +++ b/util/swagger/swagger_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/go-openapi/loads" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/util/assets" ) @@ -38,21 +39,12 @@ func TestSwaggerUI(t *testing.T) { server := "http://" + address specDoc, err := loads.Spec(server + "/swagger.json") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = json.MarshalIndent(specDoc.Spec(), "", " ") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) resp, err := http.Get(server + "/swagger-ui") - if err != nil { - t.Fatal(err) - } - - if resp.StatusCode != http.StatusOK { - t.Fatalf("Was expecting status code 200 from swagger-ui, but got %d instead", resp.StatusCode) - } + require.NoError(t, err) + require.Equalf(t, http.StatusOK, resp.StatusCode, "Was expecting status code 200 from swagger-ui, but got %d instead", resp.StatusCode) } diff --git a/util/test/testutil.go b/util/test/testutil.go index a78fc38648d3a..a8e506300864d 100644 --- a/util/test/testutil.go +++ b/util/test/testutil.go @@ -108,6 +108,7 @@ B3XwyYtAFsaO5r7oEc1Bv6oNSbE+FNJzRdjkWEIhdLVKlepil/w= -----END RSA PRIVATE KEY-----`) func dexMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { @@ -137,6 +138,7 @@ func dexMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Re } func GetDexTestServer(t *testing.T) *httptest.Server { + t.Helper() ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Start with a placeholder. We need the server URL before setting up the real handler. })) @@ -147,6 +149,7 @@ func GetDexTestServer(t *testing.T) *httptest.Server { } func oidcMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Request) { + t.Helper() return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.RequestURI { @@ -200,6 +203,7 @@ func oidcMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.R } func GetOIDCTestServer(t *testing.T) *httptest.Server { + t.Helper() ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Start with a placeholder. We need the server URL before setting up the real handler. })) diff --git a/util/tls/tls_test.go b/util/tls/tls_test.go index 69f7f7f60ef7f..d164c68b233f1 100644 --- a/util/tls/tls_test.go +++ b/util/tls/tls_test.go @@ -187,22 +187,19 @@ func TestGenerate(t *testing.T) { t.Run("Invalid: No hosts specified", func(t *testing.T) { opts := CertOptions{Hosts: []string{}, Organization: "Acme", ValidFrom: time.Now(), ValidFor: 10 * time.Hour} _, _, err := generate(opts) - require.Error(t, err) - assert.Contains(t, err.Error(), "hosts not supplied") + assert.ErrorContains(t, err, "hosts not supplied") }) t.Run("Invalid: No organization specified", func(t *testing.T) { opts := CertOptions{Hosts: []string{"localhost"}, Organization: "", ValidFrom: time.Now(), ValidFor: 10 * time.Hour} _, _, err := generate(opts) - require.Error(t, err) - assert.Contains(t, err.Error(), "organization not supplied") + assert.ErrorContains(t, err, "organization not supplied") }) t.Run("Invalid: Unsupported curve specified", func(t *testing.T) { opts := CertOptions{Hosts: []string{"localhost"}, Organization: "Acme", ECDSACurve: "Curve?", ValidFrom: time.Now(), ValidFor: 10 * time.Hour} _, _, err := generate(opts) - require.Error(t, err) - assert.Contains(t, err.Error(), "Unrecognized elliptic curve") + assert.ErrorContains(t, err, "Unrecognized elliptic curve") }) for _, curve := range []string{"P224", "P256", "P384", "P521"} { diff --git a/util/util.go b/util/util.go index f7a8d8e39a401..862d3848984ba 100644 --- a/util/util.go +++ b/util/util.go @@ -3,6 +3,8 @@ package util import ( "crypto/rand" "encoding/base64" + + apiv1 "k8s.io/api/core/v1" ) // MakeSignature generates a cryptographically-secure pseudo-random token, based on a given number of random bytes, for signing purposes. @@ -16,3 +18,15 @@ func MakeSignature(size int) ([]byte, error) { b = []byte(base64.StdEncoding.EncodeToString(b)) return b, err } + +// SecretCopy generates a deep copy of a slice containing secrets +// +// This function takes a slice of pointers to Secrets and returns a new slice +// containing deep copies of the original secrets. +func SecretCopy(secrets []*apiv1.Secret) []*apiv1.Secret { + secretsCopy := make([]*apiv1.Secret, len(secrets)) + for i, secret := range secrets { + secretsCopy[i] = secret.DeepCopy() + } + return secretsCopy +} diff --git a/util/util_test.go b/util/util_test.go index ff7674419cab3..1edafb9350491 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -4,6 +4,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + apiv1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-cd/v2/util" "github.com/argoproj/argo-cd/v2/util/webhook" @@ -39,3 +41,42 @@ func TestParseRevision(t *testing.T) { }) } } + +func TestSecretCopy(t *testing.T) { + type args struct { + secrets []*apiv1.Secret + } + tests := []struct { + name string + args args + want []*apiv1.Secret + }{ + {name: "nil", args: args{secrets: nil}, want: []*apiv1.Secret{}}, + { + name: "Three", args: args{secrets: []*apiv1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "one"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "two"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "three"}}, + }}, + want: []*apiv1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "one"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "two"}}, + {ObjectMeta: metav1.ObjectMeta{Name: "three"}}, + }, + }, + { + name: "One", args: args{secrets: []*apiv1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}}, + want: []*apiv1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "one"}}}, + }, + {name: "Zero", args: args{secrets: []*apiv1.Secret{}}, want: []*apiv1.Secret{}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + secretsCopy := util.SecretCopy(tt.args.secrets) + assert.Equalf(t, tt.want, secretsCopy, "SecretCopy(%v)", tt.args.secrets) + for i := range tt.args.secrets { + assert.NotSame(t, secretsCopy[i], tt.args.secrets[i]) + } + }) + } +} diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go index 5f18a650eb97d..df5c1fecc1273 100644 --- a/util/webhook/webhook.go +++ b/util/webhook/webhook.go @@ -36,6 +36,7 @@ import ( type settingsSource interface { GetAppInstanceLabelKey() (string, error) GetTrackingMethod() (string, error) + GetInstallationID() (string, error) } // https://www.rfc-editor.org/rfc/rfc3986#section-3.2.1 @@ -273,6 +274,11 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) { return } + installationID, err := a.settingsSrc.GetInstallationID() + if err != nil { + log.Warnf("Failed to get installation ID: %v", err) + return + } trackingMethod, err := a.settingsSrc.GetTrackingMethod() if err != nil { log.Warnf("Failed to get trackingMethod: %v", err) @@ -313,7 +319,7 @@ func (a *ArgoCDWebhookHandler) HandleEvent(payload interface{}) { // No need to refresh multiple times if multiple sources match. break } else if change.shaBefore != "" && change.shaAfter != "" { - if err := a.storePreviouslyCachedManifests(&app, change, trackingMethod, appInstanceLabelKey); err != nil { + if err := a.storePreviouslyCachedManifests(&app, change, trackingMethod, appInstanceLabelKey, installationID); err != nil { log.Warnf("Failed to store cached manifests of previous revision for app '%s': %v", app.Name, err) } } @@ -343,7 +349,7 @@ func getWebUrlRegex(webURL string) (*regexp.Regexp, error) { return repoRegexp, nil } -func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Application, change changeInfo, trackingMethod string, appInstanceLabelKey string) error { +func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Application, change changeInfo, trackingMethod string, appInstanceLabelKey string, installationID string) error { err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, a.db) if err != nil { return fmt.Errorf("error validating destination: %w", err) @@ -369,7 +375,7 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl source := app.Spec.GetSource() cache.LogDebugManifestCacheKeyFields("moving manifests cache", "webhook app revision changed", change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil) - if err := a.repoCache.SetNewRevisionManifests(change.shaAfter, change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil); err != nil { + if err := a.repoCache.SetNewRevisionManifests(change.shaAfter, change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil, installationID); err != nil { return fmt.Errorf("error setting new revision manifests: %w", err) } diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go index 82cc353a8364c..9dd4695918e30 100644 --- a/util/webhook/webhook_test.go +++ b/util/webhook/webhook_test.go @@ -49,6 +49,10 @@ func (f fakeSettingsSrc) GetTrackingMethod() (string, error) { return "", nil } +func (f fakeSettingsSrc) GetInstallationID() (string, error) { + return "", nil +} + type reactorDef struct { verb string resource string @@ -56,7 +60,7 @@ type reactorDef struct { } func NewMockHandler(reactor *reactorDef, applicationNamespaces []string, objects ...runtime.Object) *ArgoCDWebhookHandler { - defaultMaxPayloadSize := int64(1) * 1024 * 1024 * 1024 + defaultMaxPayloadSize := int64(50) * 1024 * 1024 return NewMockHandlerWithPayloadLimit(reactor, applicationNamespaces, defaultMaxPayloadSize, objects...) } @@ -241,7 +245,7 @@ func TestGitHubCommitEvent_AppsInOtherNamespaces(t *testing.T) { }, }, ) - req := httptest.NewRequest("POST", "/api/webhook", nil) + req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil) req.Header.Set("X-GitHub-Event", "push") eventJSON, err := os.ReadFile("testdata/github-commit-event.json") require.NoError(t, err) @@ -424,7 +428,7 @@ func TestInvalidEvent(t *testing.T) { close(h.queue) h.Wait() assert.Equal(t, http.StatusBadRequest, w.Code) - expectedLogResult := "Webhook processing failed: The payload is either too large or corrupted. Please check the payload size (must be under 1024 MB) and ensure it is valid JSON" + expectedLogResult := "Webhook processing failed: The payload is either too large or corrupted. Please check the payload size (must be under 50 MB) and ensure it is valid JSON" assert.Equal(t, expectedLogResult, hook.LastEntry().Message) assert.Equal(t, expectedLogResult+"\n", w.Body.String()) hook.Reset()