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 6096d78c40cde..a48fea97ea7fe 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@c3a1bb2c992d77180ae65be6ae6c166cf40f857c # v45.0.3 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: Restore go build cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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.61.0 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + 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@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 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@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ui/node_modules key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }} @@ -373,7 +376,7 @@ jobs: 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 - 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@884b79409bbd464b2a59edc326a4b77dc56b2195 # v2.2 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 @@ -429,7 +432,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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: ${{ env.GOLANG_VERSION }} - name: GH actions workaround - Kill XSP4 process @@ -448,7 +451,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@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 with: path: ~/.cache/go-build key: ${{ runner.os }}-go-build-v1-${{ github.run_id }} @@ -506,13 +509,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 fb8de2bb20cda..634fbb2647787 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ jobs: actions: read # for github/codeql-action/init to get workflow details contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/autobuild to send a status report - if: github.repository == 'argoproj/argo-cd' + if: github.repository == 'argoproj/argo-cd' || vars.enable_codeql # CodeQL runs on ubuntu-latest and windows-latest runs-on: ubuntu-22.04 @@ -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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version-file: go.mod diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index f4b7a851816a8..571f7b6f31ab6 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -69,15 +69,15 @@ jobs: if: ${{ github.ref_type != 'tag'}} - name: Setup Golang - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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 +143,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 #v6.7.0 + uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 #v6.9.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/init-release.yaml b/.github/workflows/init-release.yaml index 20bb6205c9f78..8353e8a67ae84 100644 --- a/.github/workflows/init-release.yaml +++ b/.github/workflows/init-release.yaml @@ -64,7 +64,7 @@ jobs: git stash pop - name: Create pull request - uses: peter-evans/create-pull-request@6cd32fd93684475c31847837f87bb135d40a2b79 # v7.0.3 + uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 with: commit-message: "Bump version to ${{ inputs.TARGET_VERSION }}" title: "Bump version to ${{ inputs.TARGET_VERSION }} on ${{ inputs.TARGET_BRANCH }} branch" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 12cb17fcfe6fd..39c3689c7257e 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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.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@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9 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 @@ -295,7 +293,7 @@ jobs: if: ${{ env.UPDATE_VERSION == 'true' }} - name: Create PR to update VERSION on master branch - uses: peter-evans/create-pull-request@6cd32fd93684475c31847837f87bb135d40a2b79 # v7.0.3 + uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 with: commit-message: Bump version in master title: "chore: Bump version in master" 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..b2159df9de48e 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -20,8 +20,10 @@ linters: - misspell - staticcheck - testifylint + - thelper - unparam - unused + - usestdlibvars - whitespace linters-settings: gocritic: 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 71799e918f94d..ec12fb873ea9e 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.8.0@sha256:bd00c03095f7586432805dbf7989be10361d27987f93de904b1fc003949a4794 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 diff --git a/Makefile b/Makefile index d6f8cdf62d5d8..c1ef27163cc60 100644 --- a/Makefile +++ b/Makefile @@ -486,6 +486,7 @@ 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 \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} diff --git a/README.md b/README.md index 397c51161e0b4..b369043821010 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![codecov](https://codecov.io/gh/argoproj/argo-cd/branch/master/graph/badge.svg)](https://codecov.io/gh/argoproj/argo-cd) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4486/badge)](https://bestpractices.coreinfrastructure.org/projects/4486) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/argoproj/argo-cd/badge)](https://scorecard.dev/viewer/?uri=github.com/argoproj/argo-cd) -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fargoproj%2Fargo-cd.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fargoproj%2Fargo-cd?ref=badge_shield) **Social:** [![Twitter Follow](https://img.shields.io/twitter/follow/argoproj?style=social)](https://twitter.com/argoproj) @@ -57,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 a56c3beea42da..815300ca64f49 100644 --- a/USERS.md +++ b/USERS.md @@ -16,6 +16,7 @@ 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. [Albert Heijn](https://ah.nl/) 1. [Alibaba Group](https://www.alibabagroup.com/) 1. [Allianz Direct](https://www.allianzdirect.de/) @@ -35,12 +36,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 +78,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 +88,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 +119,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 +248,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 +277,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/) @@ -306,6 +314,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Skyscanner](https://www.skyscanner.net/) 1. [Smart Pension](https://www.smartpension.co.uk/) 1. [Smilee.io](https://smilee.io) +1. [Smilegate Stove](https://www.onstove.com/) 1. [Smood.ch](https://www.smood.ch/) 1. [Snapp](https://snapp.ir/) 1. [Snyk](https://snyk.io/) @@ -329,10 +338,12 @@ Currently, the following organizations are **officially** using Argo CD: 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) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index d3911f1e0c7c4..7df5c46bfc16d 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -52,7 +52,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 +78,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 @@ -97,6 +95,7 @@ type ApplicationSetReconciler struct { // +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) { + startReconcile := time.Now() logCtx := log.WithField("applicationset", req.NamespacedName) var applicationSetInfo argov1alpha1.ApplicationSet @@ -334,7 +333,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 +471,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 +995,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 +1018,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 +1047,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: fmt.Sprint(getAppStep(app.Name, appStepMap)), TargetRevisions: app.Status.GetRevisions(), } } else { @@ -1061,7 +1072,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 = fmt.Sprint(getAppStep(currentAppStatus.Application, appStepMap)) currentAppStatus.TargetRevisions = app.Status.GetRevisions() } @@ -1079,14 +1090,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 = fmt.Sprint(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 = fmt.Sprint(getAppStep(currentAppStatus.Application, appStepMap)) } } @@ -1095,7 +1106,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 = fmt.Sprint(getAppStep(currentAppStatus.Application, appStepMap)) } if currentAppStatus.Status == "Progressing" && isApplicationHealthy(app) { @@ -1103,7 +1114,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 = fmt.Sprint(getAppStep(currentAppStatus.Application, appStepMap)) } appStatuses = append(appStatuses, currentAppStatus) @@ -1124,14 +1135,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 +1150,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 +1176,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 +1185,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 = fmt.Sprint(getAppStep(appStatus.Application, appStepMap)) updateCountMap[appStepMap[appStatus.Application]] += 1 } @@ -1484,7 +1491,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..b33465a679caa 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{ @@ -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{ @@ -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 @@ -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 @@ -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,12 +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", @@ -1945,6 +1920,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 +2053,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{ @@ -2094,21 +2072,15 @@ func TestValidateGeneratedApplications(t *testing.T) { 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: &argoDBMock, + ArgoCDNamespace: "namespace", + KubeClientset: kubeclientset, + Metrics: metrics, } appSetInfo := v1alpha1.ApplicationSet{} @@ -2150,8 +2122,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"}, @@ -2190,9 +2160,8 @@ 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"} @@ -2210,12 +2179,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: &argoDBMock, + KubeClientset: kubeclientset, + Policy: v1alpha1.ApplicationsSyncPolicySync, + ArgoCDNamespace: "argocd", + Metrics: metrics, } req := ctrl.Request{ @@ -2246,8 +2214,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 +2246,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 +2282,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 +2345,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 @@ -2395,7 +2364,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 +2377,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } for _, condition := range testCase.conditions { @@ -2425,11 +2392,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"}, @@ -2469,9 +2435,8 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp kubeclientset := kubefake.NewSimpleClientset() argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&defaultProject} - 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) @@ -2489,7 +2454,6 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, ArgoDB: &argoDBMock, ArgoCDNamespace: "argocd", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, @@ -2590,11 +2554,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"}, @@ -2634,9 +2597,8 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp kubeclientset := kubefake.NewSimpleClientset() argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&defaultProject} - 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) @@ -2654,7 +2616,6 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp }, ArgoDB: &argoDBMock, ArgoCDNamespace: "argocd", - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, @@ -2752,9 +2713,6 @@ 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"}}}, @@ -2767,7 +2725,6 @@ func TestPolicies(t *testing.T) { 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 +2796,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 +2807,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: &argoDBMock, + ArgoCDNamespace: "argocd", + KubeClientset: kubeclientset, + Policy: policy, + Metrics: metrics, } req := ctrl.Request{ @@ -2923,12 +2879,9 @@ 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 +2965,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } err = r.setAppSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) @@ -3031,9 +2983,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) @@ -3766,17 +3715,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } appDependencyList, appStepMap := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps) @@ -3791,9 +3738,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 +3757,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 +3783,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 +3815,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 +3847,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 +3925,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 +4003,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 +4081,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 +4159,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 +4237,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{ @@ -4357,17 +4382,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } appSyncMap := r.buildAppSyncMap(cc.appSet, cc.appDependencyList, cc.appMap) @@ -4381,9 +4404,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 +4420,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 +4446,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 +4478,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4459,8 +4500,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 +4533,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4502,8 +4555,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 +4597,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4554,8 +4619,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 +4675,10 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + "app2-multisource": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4627,8 +4705,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 +4742,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4674,8 +4764,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 +4807,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4727,8 +4829,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 +4872,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4780,8 +4894,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 +4937,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4833,8 +4959,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 +5018,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 +5077,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -4952,8 +5099,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 +5158,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5021,8 +5180,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 +5238,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5089,8 +5260,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 +5310,9 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + appStepMap: map[string]int{ + "app1": 0, + }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { Application: "app1", @@ -5144,20 +5327,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) @@ -5178,9 +5359,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 @@ -5898,20 +6076,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap) @@ -5932,9 +6108,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 @@ -6114,20 +6287,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: &argoDBMock, + KubeClientset: kubeclientset, + Metrics: metrics, } err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) @@ -6206,20 +6377,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: &argoDBMock, + 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_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..100e8e45022c8 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. @@ -92,6 +88,10 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap secretsFound := []corev1.Secret{} + isFlatMode := appSetGenerator.Clusters.FlatList + log.Debug("Using flat mode = ", isFlatMode, " for cluster generator") + 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,13 +103,18 @@ 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") } @@ -123,6 +128,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,11 +161,20 @@ 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") } + if isFlatMode { + res = append(res, map[string]interface{}{ + "clusters": clustersParams, + }) + } return res, nil } @@ -161,7 +182,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1 // List all Clusters: 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) 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/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/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..83d304835c70a 100644 --- a/applicationset/services/internal/http/client_test.go +++ b/applicationset/services/internal/http/client_test.go @@ -77,7 +77,7 @@ func TestClientDo(t *testing.T) { "key3": float64(123), }, }, - expectedCode: 200, + expectedCode: http.StatusOK, expectedError: nil, }, { @@ -109,7 +109,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: "), }, } { diff --git a/applicationset/services/pull_request/bitbucket_cloud_test.go b/applicationset/services/pull_request/bitbucket_cloud_test.go index 8d5f7d80ca144..2e41c110bcd92 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 @@ -233,7 +234,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") 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/gitlab_test.go b/applicationset/services/pull_request/gitlab_test.go index f9e845595e224..9abb8d73ea491 100644 --- a/applicationset/services/pull_request/gitlab_test.go +++ b/applicationset/services/pull_request/gitlab_test.go @@ -15,6 +15,7 @@ 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) 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..961c08066672d 100644 --- a/applicationset/services/scm_provider/github.go +++ b/applicationset/services/scm_provider/github.go @@ -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_test.go b/applicationset/utils/clusterUtils_test.go index 9e8694359b6bd..fdc316fbc428c 100644 --- a/applicationset/utils/clusterUtils_test.go +++ b/applicationset/utils/clusterUtils_test.go @@ -30,7 +30,7 @@ func Test_secretToCluster(t *testing.T) { Data: map[string][]byte{ "name": []byte("test"), "server": []byte("http://mycluster"), - "config": []byte("{\"username\":\"foo\"}"), + "config": []byte("{\"username\":\"foo\", \"disableCompression\":true}"), }, } cluster, err := secretToCluster(secret) @@ -39,7 +39,8 @@ func Test_secretToCluster(t *testing.T) { Name: "test", Server: "http://mycluster", Config: argoappv1.ClusterConfig{ - Username: "foo", + Username: "foo", + DisableCompression: true, }, }, *cluster) } 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/assets/swagger.json b/assets/swagger.json index 1e8a981c51c66..fb78f9420dc12 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -4557,6 +4557,9 @@ "namespace": { "type": "string" }, + "requiresDeletionConfirmation": { + "type": "boolean" + }, "requiresPruning": { "type": "boolean" }, @@ -4719,6 +4722,9 @@ "impersonationEnabled": { "type": "boolean" }, + "installationID": { + "type": "string" + }, "kustomizeOptions": { "$ref": "#/definitions/v1alpha1KustomizeOptions" }, @@ -6084,7 +6090,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.", @@ -6614,6 +6620,10 @@ "type": "boolean", "title": "SkipCrds skips custom resource definition installation step (Helm's --skip-crds)" }, + "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", @@ -7137,12 +7147,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 +7174,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" }, @@ -9167,6 +9189,11 @@ "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" diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 1d193154e0edd..0468e4fd473dc 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -13,6 +13,7 @@ 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" @@ -24,6 +25,7 @@ import ( appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" @@ -56,6 +58,9 @@ func NewCommand() *cobra.Command { repoServerAddress string repoServerTimeoutSeconds int selfHealTimeoutSeconds int + selfHealBackoffTimeoutSeconds int + selfHealBackoffFactor int + selfHealBackoffCapSeconds int statusProcessors int operationProcessors int glogLevel int @@ -78,6 +83,9 @@ func NewCommand() *cobra.Command { enableDynamicClusterDistribution bool serverSideDiff bool ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts + + // argocd k8s event logging flag + enableK8sEvent []string ) command := cobra.Command{ Use: cliName, @@ -152,6 +160,14 @@ 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, @@ -164,6 +180,7 @@ func NewCommand() *cobra.Command { hardResyncDuration, time.Duration(appResyncJitter)*time.Second, time.Duration(selfHealTimeoutSeconds)*time.Second, + selfHealBackoff, time.Duration(repoErrorGracePeriod)*time.Second, metricsPort, metricsCacheExpiration, @@ -177,6 +194,7 @@ func NewCommand() *cobra.Command { serverSideDiff, enableDynamicClusterDistribution, ignoreNormalizerOpts, + enableK8sEvent, ) errors.CheckError(err) cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) @@ -226,7 +244,10 @@ 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().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") @@ -251,6 +272,9 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.") command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")") 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)") + 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..345454b7e7a2c 100644 --- a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go +++ b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go @@ -38,7 +38,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 +72,7 @@ func NewCommand() *cobra.Command { metricsAplicationsetLabels []string enableScmProviders bool webhookParallelism int + tokenRefStrictMode bool ) scheme := runtime.NewScheme() _ = clientgoscheme.AddToScheme(scheme) @@ -162,10 +162,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 +210,6 @@ func NewCommand() *cobra.Command { Renderer: &utils.Render{}, Policy: policyObj, EnablePolicyOverride: enablePolicyOverride, - ArgoAppClientset: appSetConfig, KubeClientset: k8sClient, ArgoDB: argoCDDB, ArgoCDNamespace: namespace, @@ -252,6 +250,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-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-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index ec863c26647f0..f8bb868f0bd0f 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -75,6 +75,7 @@ func NewCommand() *cobra.Command { helmRegistryMaxIndexSize string disableManifestMaxExtractedSize bool includeHiddenDirectories bool + cmpUseManifestGeneratePaths bool ) command := cobra.Command{ Use: cliName, @@ -136,6 +137,7 @@ func NewCommand() *cobra.Command { HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(), HelmRegistryMaxIndexSize: helmRegistryMaxIndexSizeQuantity.ToDec().Value(), IncludeHiddenDirectories: includeHiddenDirectories, + CMPUseManifestGeneratePaths: cmpUseManifestGeneratePaths, }, askPassServer) errors.CheckError(err) @@ -241,6 +243,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 c8e4596ab3a75..d1e9cf05f98d5 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -27,6 +27,7 @@ import ( reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" "github.com/argoproj/argo-cd/v2/server" servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/argo" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/dex" @@ -91,6 +92,9 @@ func NewCommand() *cobra.Command { scmRootCAPath string allowedScmProviders []string enableScmProviders bool + + // argocd k8s event logging flag + enableK8sEvent []string ) command := &cobra.Command{ Use: cliName, @@ -229,6 +233,7 @@ func NewCommand() *cobra.Command { ApplicationNamespaces: applicationNamespaces, EnableProxyExtension: enableProxyExtension, WebhookParallelism: webhookParallelism, + EnableK8sEvent: enableK8sEvent, } appsetOpts := server.ApplicationSetOpts{ @@ -303,6 +308,7 @@ func NewCommand() *cobra.Command { command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in") 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)") // 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/backup.go b/cmd/argocd/commands/admin/backup.go index 918bbc234b9a2..6b87af01d5678 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, "force-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..7841e5bab8c7b 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) }, } 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/settings.go b/cmd/argocd/commands/admin/settings.go index 7cd49b0c94031..689653cd3930b 100644 --- a/cmd/argocd/commands/admin/settings.go +++ b/cmd/argocd/commands/admin/settings.go @@ -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_test.go b/cmd/argocd/commands/admin/settings_test.go index 4db8ae7ba5eeb..ac19104a5960f 100644 --- a/cmd/argocd/commands/admin/settings_test.go +++ b/cmd/argocd/commands/admin/settings_test.go @@ -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..c48382e23fede 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -27,6 +27,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 +35,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 +100,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 } @@ -379,7 +382,8 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com }) errors.CheckError(err) - if app.Spec.HasMultipleSources() { + // 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")) } @@ -585,8 +589,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 +599,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" @@ -909,13 +914,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 +1092,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 +1152,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co refresh bool hardRefresh bool exitCode bool + diffExitCode int local string revision string localRepoRoot string @@ -1241,13 +1255,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") @@ -1374,7 +1389,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 +1444,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 +1456,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 +1478,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.") } } }, @@ -3184,17 +3190,70 @@ 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.") + 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_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/applicationset.go b/cmd/argocd/commands/applicationset.go index 4bed5aea8a992..9d8a71e0b1212 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" @@ -345,12 +345,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 +367,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.") } } }, 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..9d71af3a5ce3c 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 := "" @@ -191,6 +197,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie 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..11fd3d4ab9c66 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", 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/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..2284378731307 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, "force-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/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..4acf96f743f0c --- /dev/null +++ b/cmd/argocd/commands/utils/prompt_test.go @@ -0,0 +1,126 @@ +package utils + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +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?") + if result1 != true || result2 != true { + t.Errorf("Expected (true, true), got (%v, %v)", result1, result2) + } +} + +func TestConfirmBaseOnCountPromptDisabled(t *testing.T) { + p := &Prompt{enabled: false} + result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 2) + + if result1 != true || result2 != true { + t.Errorf("Expected (true, true), got (%v, %v)", result1, result2) + } +} + +func TestConfirmBaseOnCountZeroApps(t *testing.T) { + p := &Prompt{enabled: true} + result1, result2 := p.ConfirmBaseOnCount("Proceed?", "Process all?", 0) + + if result1 != true || result2 != true { + t.Errorf("Expected (true, true), got (%v, %v)", result1, 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) + if err != nil { + t.Fatal(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) + if err != nil { + t.Fatal(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/main.go b/cmd/main.go index e6c94c40f7c85..fcf771cc1512c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,9 +4,9 @@ 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" @@ -31,9 +31,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 +45,24 @@ func main() { command = reposerver.NewCommand() case "argocd-cmp-server": command = cmpserver.NewCommand() + isCLI = true 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..025ef968097e5 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,7 @@ type AppOptions struct { helmVersion string helmPassCredentials bool helmSkipCrds bool + helmSkipTests bool helmNamespace string helmKubeVersion string helmApiVersions []string @@ -88,6 +91,19 @@ type AppOptions struct { ref 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) { command.Flags().StringVar(&opts.repoURL, "repo", "", "Repository URL, ignored if a file is set") command.Flags().StringVar(&opts.appPath, "path", "", "Path in repository to the app directory, ignored if a file is set") @@ -109,6 +125,7 @@ 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.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") @@ -358,6 +375,7 @@ type helmOpts struct { helmSetFiles []string passCredentials bool skipCrds bool + skipTests bool namespace string kubeVersion string apiVersions []string @@ -391,6 +409,9 @@ func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) { if opts.skipCrds { src.Helm.SkipCrds = opts.skipCrds } + if opts.skipTests { + src.Helm.SkipTests = opts.skipTests + } if opts.namespace != "" { src.Helm.Namespace = opts.namespace } @@ -658,6 +679,8 @@ 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-tests": + setHelmOpt(source, helmOpts{skipTests: appOpts.helmSkipTests}) case "helm-namespace": setHelmOpt(source, helmOpts{namespace: appOpts.helmNamespace}) case "helm-kube-version": diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index 595b9be46563e..f9967d6d0cae8 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,11 @@ func Test_setHelmOpt(t *testing.T) { setHelmOpt(&src, helmOpts{skipCrds: true}) assert.True(t, src.Helm.SkipCrds) }) + 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"}) @@ -529,3 +535,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..3e59dc466c1a0 100644 --- a/cmd/util/cluster_test.go +++ b/cmd/util/cluster_test.go @@ -37,6 +37,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 +74,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) { 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/common/common.go b/common/common.go index 79fcdba195eb6..d2e47aa5b1607 100644 --- a/common/common.go +++ b/common/common.go @@ -175,9 +175,12 @@ const ( LabelValueSecretTypeRepository = "repository" // LabelValueSecretTypeRepoCreds indicates a secret type of repository credentials LabelValueSecretTypeRepoCreds = "repo-creds" + // 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" @@ -315,7 +318,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 +431,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 +443,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..4db2ad76ce037 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -63,24 +63,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{}, }, }, @@ -101,8 +101,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 e64db6eae2ecc..5a48f1d41cb09 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -130,7 +130,7 @@ type ApplicationController struct { statusHardRefreshTimeout time.Duration statusRefreshJitter time.Duration selfHealTimeout time.Duration - repoClientset apiclient.Clientset + selfHealBackOff *wait.Backoff db db.ArgoDB settingsMgr *settings_util.SettingsManager refreshRequestedApps map[string]CompareWith @@ -160,6 +160,7 @@ func NewApplicationController( appHardResyncPeriod time.Duration, appResyncJitter time.Duration, selfHealTimeout time.Duration, + selfHealBackoff *wait.Backoff, repoErrorGracePeriod time.Duration, metricsPort int, metricsCacheExpiration time.Duration, @@ -173,6 +174,7 @@ func NewApplicationController( serverSideDiff bool, dynamicClusterDistributionEnabled bool, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts, + enableK8sEvent []string, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter) db := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -186,7 +188,6 @@ 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"}), @@ -197,9 +198,10 @@ func NewApplicationController( statusRefreshJitter: appResyncJitter, refreshRequestedApps: make(map[string]CompareWith), refreshRequestedAppsMutex: &sync.Mutex{}, - auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), + auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController, enableK8sEvent), settingsMgr: settingsMgr, selfHealTimeout: selfHealTimeout, + selfHealBackOff: selfHealBackoff, clusterSharding: clusterSharding, projByNameCache: sync.Map{}, applicationNamespaces: applicationNamespaces, @@ -626,6 +628,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() @@ -757,7 +760,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) } @@ -1162,9 +1165,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) @@ -1182,6 +1191,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 + } } } @@ -1690,7 +1703,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 { @@ -1980,6 +1994,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 } @@ -1997,6 +2014,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{ @@ -2115,10 +2133,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 } diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index d6311cb30b7ca..6ed07aba702e5 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -4,16 +4,18 @@ import ( "context" "encoding/json" "errors" + "fmt" "testing" "time" + clustercache "github.com/argoproj/gitops-engine/pkg/cache" "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/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" @@ -43,12 +45,15 @@ import ( "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" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" "github.com/argoproj/argo-cd/v2/util/settings" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + type namespacedResource struct { v1alpha1.ResourceNode AppName string @@ -64,6 +69,7 @@ type fakeData struct { metricsCacheExpiration time.Duration applicationNamespaces []string updateRevisionForPathsResponse *apiclient.UpdateRevisionForPathsResponse + additionalObjs []runtime.Object } type MockKubectl struct { @@ -133,7 +139,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.NewSimpleClientset(runtimeObjs...) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) kubectl := &MockKubectl{Kubectl: &kubetest.MockKubectlCmd{}} ctrl, err := NewApplicationController( @@ -151,6 +159,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { time.Hour, time.Second, time.Minute, + nil, time.Second*10, common.DefaultPortArgoCDMetrics, data.metricsCacheExpiration, @@ -164,6 +173,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { false, false, normalizers.IgnoreNormalizerOpts{}, + testEnableEventList, ) db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) @@ -813,6 +823,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", @@ -833,11 +844,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] @@ -876,6 +885,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) @@ -921,10 +931,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] @@ -2184,3 +2192,67 @@ func TestAlreadyAttemptSync(t *testing.T) { assert.False(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) + }) + } +} diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 170f5118b521a..b17afbca5234b 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -197,6 +197,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 +226,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 +251,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 +495,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 +531,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 } @@ -821,7 +829,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/info.go b/controller/cache/info.go index 0734e2d118678..7260487af859f 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" } 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/metrics/metrics.go b/controller/metrics/metrics.go index a9df75aff8015..b8674cd231b09 100644 --- a/controller/metrics/metrics.go +++ b/controller/metrics/metrics.go @@ -33,6 +33,7 @@ type MetricsServer struct { syncCounter *prometheus.CounterVec kubectlExecCounter *prometheus.CounterVec kubectlExecPendingGauge *prometheus.GaugeVec + orphanedResourcesGauge *prometheus.GaugeVec k8sRequestCounter *prometheus.CounterVec clusterEventsCounter *prometheus.CounterVec redisRequestCounter *prometheus.CounterVec @@ -144,6 +145,14 @@ var ( }, []string{"hostname", "initiator"}, ) + + orphanedResourcesGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "argocd_app_orphaned_resources_count", + Help: "Number of orphaned resources per application", + }, + descAppDefaultLabels, + ) ) // NewMetricsServer returns a new prometheus server which collects application metrics @@ -188,6 +197,7 @@ 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) @@ -203,6 +213,7 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil k8sRequestCounter: k8sRequestCounter, kubectlExecCounter: kubectlExecCounter, kubectlExecPendingGauge: kubectlExecPendingGauge, + orphanedResourcesGauge: orphanedResourcesGauge, reconcileHistogram: reconcileHistogram, clusterEventsCounter: clusterEventsCounter, redisRequestCounter: redisRequestCounter, @@ -241,6 +252,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() @@ -290,6 +305,7 @@ 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() 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..5c36a0851919d 100644 --- a/controller/sharding/sharding_test.go +++ b/controller/sharding/sharding_test.go @@ -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/state.go b/controller/state.go index bcac67961781c..b6bafcb5c83ac 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" @@ -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 { @@ -230,6 +236,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp 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 +256,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: 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, + 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 +300,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 } @@ -353,20 +363,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 } - return appLabelKey, resourceOverrides, resFilter, nil + installationID, err := m.settingsMgr.GetInstallationID() + if err != nil { + return "", nil, nil, "", err + } + return appLabelKey, resourceOverrides, resFilter, installationID, nil } // verifyGnuPGSignature verifies the result of a GnuPG operation for a given git @@ -417,7 +431,7 @@ 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") @@ -585,7 +599,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 +738,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 +748,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 +940,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 +949,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 +1066,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 +1099,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..658e72224aeb9 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) { @@ -1372,8 +1371,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 +1380,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 +1426,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 +1528,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 +1697,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..a553fd3e37cf7 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" @@ -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/docs/assets/okta-auth-policy-edit.png b/docs/assets/okta-auth-policy-edit.png new file mode 100644 index 0000000000000..91395dcf5b074 Binary files /dev/null and b/docs/assets/okta-auth-policy-edit.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/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/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/getting_started.md b/docs/getting_started.md index ce0d9688e7963..74623e3f08209 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: 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/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/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/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..e00c2f420d240 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: "1024" - # 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..37aaadd12a4d4 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -47,8 +47,11 @@ 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" + # 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) @@ -171,6 +174,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. @@ -239,6 +244,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/argocd-repositories.yaml b/docs/operator-manual/argocd-repositories.yaml index b6aa0715c389d..8f48429ebd60b 100644 --- a/docs/operator-manual/argocd-repositories.yaml +++ b/docs/operator-manual/argocd-repositories.yaml @@ -12,6 +12,7 @@ stringData: url: https://github.com/argoproj/argocd-example-apps password: my-password username: my-username + project: my-project insecure: "true" # Ignore validity of server's TLS certificate. Defaults to "false" forceHttpBasicAuth: "true" # Skip auth method negotiation and force usage of HTTP basic auth. Defaults to "false" enableLfs: "true" # Enable git-lfs for this repository. Defaults to "false" @@ -42,6 +43,7 @@ metadata: stringData: url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts name: istio.io + project: my-project type: helm --- apiVersion: v1 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 7d892114c367b..d3b93d27c1601 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -30,7 +30,7 @@ For each specific kind of ConfigMap and Secret resource, there is only a single |------------------------------------------------------------------|-------------|--------------------------| | [`application.yaml`](../user-guide/application-specification.md) | Application | Example application spec | | [`project.yaml`](./project-specification.md) | AppProject | Example project spec | -| - | Secret | Repository credentials | +| [`argocd-repositories.yaml`](./argocd-repositories-yaml.md) | Secret | Repository credentials | For `Application` and `AppProject` resources, the name of the resource equals the name of the application or project within Argo CD. This also means that application and project names are unique within a given Argo CD installation - you cannot have the same application name for two different applications. @@ -176,6 +176,7 @@ spec: Repository details are stored in secrets. To configure a repo, create a secret which contains repository details. Consider using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) to store an encrypted secret definition as a Kubernetes manifest. Each repository must have a `url` field and, depending on whether you connect using HTTPS, SSH, or GitHub App, `username` and `password` (for HTTPS), `sshPrivateKey` (for SSH), or `githubAppPrivateKey` (for GitHub App). +Credentials can be scoped to a project using the optional `project` field. When omitted, the credential will be used as the default for all projects without a scoped credential. !!!warning When using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) the labels will be removed and have to be readded as described here: https://github.com/bitnami-labs/sealed-secrets#sealedsecrets-as-templates-for-secrets @@ -195,6 +196,7 @@ stringData: url: https://github.com/argoproj/private-repo password: my-password username: my-username + project: my-project ``` Example for SSH: @@ -565,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). @@ -579,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). @@ -619,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": { @@ -634,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" @@ -654,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" } } @@ -663,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 @@ -695,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 { @@ -732,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: @@ -785,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 @@ -1044,7 +1165,7 @@ stringData: ## Resource Exclusion/Inclusion -Resources can be excluded from discovery and sync so that Argo CD is unaware of them. For example, the apiGroup/kind `events.k8s.io/*`, `metrics.k8s.io/*`, `coordination.k8s.io/Lease`, and `""/Endpoints` are always excluded. Use cases: +Resources can be excluded from discovery and sync so that Argo CD is unaware of them. For example, the apiGroup/kind `events.k8s.io/*`, `metrics.k8s.io/*` and `coordination.k8s.io/Lease` are always excluded. Use cases: * You have temporal issues and you want to exclude problematic resources. * There are many of a kind of resources that impacts Argo CD's performance. @@ -1104,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..c034157e7f22e 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 diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index 7808bfd677bfd..ddcce80fab25a 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -277,6 +277,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/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/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 9b8044e9e0ffd..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 @@ -110,7 +119,7 @@ data: jqPathExpressions: # Ignore lastTransitionTime for conditions; helpful when SharedResourceWarnings are being regularly updated but not # actually changing in content. - - .status.conditions[].lastTransitionTime + - .status?.conditions[]?.lastTransitionTime ``` ## Ignoring updates for untracked resources 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 78a80e14d66a4..07fd9e545c8d4 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -31,6 +31,7 @@ argocd-application-controller [flags] --default-cache-expiration duration Cache expiration default (default 24h0m0s) --disable-compression If true, opt-out of response compression for all requests to the server --dynamic-cluster-distribution-enabled Enables dynamic cluster distribution. + --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 --ignore-normalizer-jq-execution-timeout-seconds duration Set ignore normalizer JQ execution timeout @@ -66,7 +67,10 @@ 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 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 2f022f3da2be0..0fe1e2d3ca45e 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -51,6 +51,7 @@ argocd-server [flags] --disable-auth Disable client authentication --disable-compression If true, opt-out of response compression for all requests to the server --enable-gzip Enable GZIP compression (default true) + --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]) --enable-proxy-extension Enable Proxy Extension feature --gloglevel int Set the glog logging level -h, --help help for argocd-server 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/okta.md b/docs/operator-manual/user-management/okta.md index 5ce5f08e250fc..4fd7ea0dc734c 100644 --- a/docs/operator-manual/user-management/okta.md +++ b/docs/operator-manual/user-management/okta.md @@ -135,7 +135,7 @@ First, create the OIDC integration: ![Okta OIDC app dialogue](../../assets/okta-create-oidc-app.png) 1. Update the following: 1. `App Integration name` and `Logo` - set these to suit your needs; they'll be displayed in the Okta catalogue. - 1. `Sign-in redirect URLs`: Add `https://argocd.example.com/auth/callback`; replacing `argocd.example.com` with your ArgoCD web interface URL. Also add `http://localhost:8085/auth/callback` if you would like to be able to login with the CLI. + 1. `Sign-in redirect URLs`: Add `https://argocd.example.com/auth/callback`; replacing `argocd.example.com` with your ArgoCD web interface URL. 1. `Sign-out redirect URIs`: Add `https://argocd.example.com`; substituting the correct domain name as above. 1. Either assign groups, or choose to skip this step for now. 1. Leave the rest of the options as-is, and save the integration. @@ -170,6 +170,25 @@ Next, create a custom Authorization server: ![Default rule](../../assets/okta-auth-rule.png) 1. Finally, click `Back to Authorization Servers`, and copy the `Issuer URI`. You will need this later. +### CLI login + +In order to login with the CLI `argocd login https://argocd.example.com --sso`, Okta requires a separate dedicated App Integration: + +1. Create a new `Create App Integration`, and choose `OIDC`, and then `Single-Page Application`. +1. Update the following: + 1. `App Integration name` and `Logo` - set these to suit your needs; they'll be displayed in the Okta catalogue. + 1. `Sign-in redirect URLs`: Add `http://localhost:8085/auth/callback`. + 1. `Sign-out redirect URIs`: Add `http://localhost:8085`. + 1. Either assign groups, or choose to skip this step for now. + 1. Leave the rest of the options as-is, and save the integration. + 1. Copy the `Client ID` from the newly created app; `cliClientID: ` will be used in your `argocd-cm` ConfigMap. +1. Edit your Authorization Server `Access Policies`: + 1. Navigate to the Okta API Management at `Security > API`. + 1. Choose your existing `Authorization Server` that was created previously. + 1. Click `Access Policies` > `Edit Policy`. + 1. Assign your newly created `App Integration` by filling in the text box and clicking `Update Policy`. + ![Edit Policy](../../assets/okta-auth-policy-edit.png) + If you haven't yet created Okta groups, and assigned them to the application integration, you should do that now: 1. Go to `Directory > Groups` @@ -190,6 +209,7 @@ oidc.config: | # this is the authorization server URI issuer: https://example.okta.com/oauth2/aus9abcdefgABCDEFGd7 clientID: 0oa9abcdefgh123AB5d7 + cliClientID: gfedcba0987654321GEFDCBA # Optional if using the CLI for SSO clientSecret: ABCDEFG1234567890abcdefg requestedScopes: ["openid", "profile", "email", "groups"] requestedIDTokenClaims: {"groups": {"essential": true}} 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/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..2dbcb9bb89f85 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -13,52 +13,66 @@ 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 | 7 | 0 | +| [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 0 | 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 | 2 | 9 | +| [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.0-rc5 | | 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.0-rc5/argocd-test.html) | 0 | 0 | 7 | 0 | +| [ui/yarn.lock](v2.13.0-rc5/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.41.1](v2.13.0-rc5/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 2 | +| [haproxy:2.6.17-alpine](v2.13.0-rc5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.13.0-rc5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.13.0-rc5](v2.13.0-rc5/quay.io_argoproj_argocd_v2.13.0-rc5.html) | 0 | 0 | 2 | 9 | +| [redis:7.0.15-alpine](v2.13.0-rc5/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.13.0-rc5/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.13.0-rc5/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.11.8 +### v2.12.6 | | 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.6/argocd-test.html) | 0 | 0 | 8 | 0 | +| [ui/yarn.lock](v2.12.6/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.38.0](v2.12.6/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.17-alpine](v2.12.6/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 4 | +| [redis:7.0.15-alpine](v2.12.6/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.12.6](v2.12.6/quay.io_argoproj_argocd_v2.12.6.html) | 0 | 0 | 2 | 9 | +| [redis:7.0.15-alpine](v2.12.6/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.12.6/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.12.6/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.10.16 +### v2.11.11 | | 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.11/argocd-test.html) | 0 | 1 | 9 | 0 | +| [ui/yarn.lock](v2.11.11/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.38.0](v2.11.11/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 7 | +| [haproxy:2.6.14-alpine](v2.11.11/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 7 | +| [argocd:v2.11.11](v2.11.11/quay.io_argoproj_argocd_v2.11.11.html) | 0 | 0 | 3 | 18 | +| [redis:7.0.15-alpine](v2.11.11/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.11.11/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.11.11/argocd-iac-namespace-install.html) | - | - | - | - | + +### v2.10.18 + +| | Critical | High | Medium | Low | +|---:|:--------:|:----:|:------:|:---:| +| [go.mod](v2.10.18/argocd-test.html) | 0 | 1 | 9 | 0 | +| [ui/yarn.lock](v2.10.18/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.37.0](v2.10.18/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 1 | 10 | 7 | +| [haproxy:2.6.14-alpine](v2.10.18/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 7 | +| [argocd:v2.10.18](v2.10.18/quay.io_argoproj_argocd_v2.10.18.html) | 0 | 0 | 3 | 18 | +| [redis:7.0.15-alpine](v2.10.18/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 1 | +| [install.yaml](v2.10.18/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.10.18/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..6c53ffcdfab8b 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)

+

October 27th 2024, 12:21:27 am (UTC+00:00)

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

Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Container could be running with outdated image

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

    Container could be running with outdated image

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container is running with multiple open ports

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

    Container is running without liveness probe

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

    Container is running without liveness probe

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

    Container is running without liveness probe

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

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

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

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

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

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

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

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

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

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

    Container's or Pod's UID could clash with hos
  • - Line number: 24320 + Line number: 24536
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 020a13bf79f07..786a55395053d 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)

    +

    October 27th 2024, 12:21:36 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: 2161
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 33e1e7ab43d33..03987fa4cf54f 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)

    +

    October 27th 2024, 12:19:23 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
    +
    25 vulnerable dependency paths
    +
    2137 dependencies

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

    Snyk test report

    -

    Regular Expression Denial of Service (ReDoS)

    +

    LGPL-3.0 license

    @@ -489,21 +490,205 @@

    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: + + 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: - path-to-regexp + 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 - argo-cd-ui@1.0.0, react-router@4.3.1 and others
    @@ -515,39 +700,164 @@

    Detailed paths

    • Introduced through: - argo-cd-ui@1.0.0 + 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.112.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 - react-router@4.3.1 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd - path-to-regexp@1.8.0 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.7
    • Introduced through: - argo-cd-ui@1.0.0 + 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 - react-router-dom@4.3.1 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd - react-router@4.3.1 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - path-to-regexp@1.8.0 + github.com/hashicorp/go-retryablehttp@0.7.7
    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#2fef5c9049fd - argo-ui@1.0.0 + github.com/argoproj/notifications-engine/pkg/subscriptions@#2fef5c9049fd - react-router-dom@4.3.1 + github.com/argoproj/notifications-engine/pkg/services@#2fef5c9049fd - react-router@4.3.1 + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - path-to-regexp@1.8.0 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -558,94 +868,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 +895,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/hashicorp/go-cleanhttp
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others
  • @@ -684,9 +917,120 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/Azure/kubelogin/pkg/token@0.0.20 + github.com/hashicorp/go-retryablehttp@0.7.7 - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.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.112.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.112.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@#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 + + 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@#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 + + github.com/hashicorp/go-cleanhttp@0.5.2 @@ -697,46 +1041,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

    +

    MPL-2.0 license

    @@ -747,21 +1062,81 @@

    Template Injection

    • - Manifest file: /argo-cd ui/yarn.lock + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod
    • - Package Manager: npm + 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: - dompurify + github.com/Azure/azure-sdk-for-go/sdk/azidentity
    • Introduced through: - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others
    @@ -773,11 +1148,11 @@

    Detailed paths

    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 - redoc@2.0.0-rc.64 + github.com/Azure/kubelogin/pkg/token@0.0.20 - dompurify@2.3.6 + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 @@ -789,24 +1164,40 @@

      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.

      -

      PoC

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

      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 dompurify to version 2.4.9, 3.0.11 or higher.

      +

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

      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..c15261fb118f4 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)

    +

    October 27th 2024, 12:19:31 am (UTC+00:00)

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

    Snyk test report

    -
    2 known vulnerabilities
    -
    8 vulnerable dependency paths
    +
    22 known vulnerabilities
    +
    43 vulnerable dependency paths
    969 dependencies
    @@ -546,6 +546,1227 @@

    References

    More about this vulnerability

    +
    +
    +

    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

    @@ -701,6 +1922,165 @@

    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..7961723dda063 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)

    +

    October 27th 2024, 12:19:36 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
    @@ -1297,6 +1297,198 @@

    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..ba29a36f054c4 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)

    +

    October 27th 2024, 12:19:41 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,189 @@

    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..2c79689e7d7a4 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)

    +

    October 27th 2024, 12:19:58 am (UTC+00:00)

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

    Snyk test report

    -
    12 known vulnerabilities
    -
    66 vulnerable dependency paths
    -
    2355 dependencies
    +
    18 known vulnerabilities
    +
    72 vulnerable dependency paths
    +
    2359 dependencies
    @@ -480,204 +480,6 @@

    Snyk test report

    -
    -

    CVE-2024-41996

    -
    - -
    - medium 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.3 - - 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.3 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - 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.3 - - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 - - 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

    @@ -803,7 +605,7 @@

    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 @@ -883,7 +685,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -898,7 +700,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -915,7 +717,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -930,7 +732,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -947,7 +749,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -966,7 +768,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -992,7 +794,7 @@

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 libssh/libssh-4@0.10.6-2build2 @@ -1050,7 +852,7 @@

    References

    -

    CVE-2024-8096

    +

    LGPL-3.0 license

    @@ -1061,21 +863,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 +889,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@latest + github.com/argoproj/argo-cd/v2@* - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + gopkg.in/retry.v1@v1.0.3 @@ -1102,53 +902,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 +949,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 +962,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 +1009,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/hashicorp/go-version@v1.6.0 @@ -1244,14 +1022,384 @@

      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.

      -

      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

      -
    +
    +

    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.4 + + 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.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + 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.4 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + 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

    + + +
    + + +

    CVE-2024-26458

    @@ -1310,7 +1656,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1325,7 +1671,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1342,7 +1688,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1357,7 +1703,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1374,7 +1720,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1393,7 +1739,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1419,7 +1765,7 @@

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 libssh/libssh-4@0.10.6-2build2 @@ -1518,7 +1864,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1533,7 +1879,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1550,7 +1896,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1565,7 +1911,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1582,7 +1928,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1601,7 +1947,7 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1627,7 +1973,7 @@

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 libssh/libssh-4@0.10.6-2build2 diff --git a/docs/snyk/master/redis_7.0.15-alpine.html b/docs/snyk/master/redis_7.0.15-alpine.html index 4048f7704e169..f4db4733e6a61 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)

    +

    October 27th 2024, 12:20: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,189 @@

    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-iac-install.html b/docs/snyk/v2.10.18/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.10.16/argocd-iac-install.html rename to docs/snyk/v2.10.18/argocd-iac-install.html index f962a3756de76..52ab9eccd0ca2 100644 --- a/docs/snyk/v2.10.16/argocd-iac-install.html +++ b/docs/snyk/v2.10.18/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:30:53 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.10.16/argocd-iac-namespace-install.html b/docs/snyk/v2.10.18/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.10.16/argocd-iac-namespace-install.html rename to docs/snyk/v2.10.18/argocd-iac-namespace-install.html index c2f25c827ce3a..093784330268c 100644 --- a/docs/snyk/v2.10.16/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.10.18/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:31:02 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.10.16/argocd-test.html b/docs/snyk/v2.10.18/argocd-test.html similarity index 93% rename from docs/snyk/v2.10.16/argocd-test.html rename to docs/snyk/v2.10.18/argocd-test.html index 7cd0e72a8b29b..424ed421c4ee4 100644 --- a/docs/snyk/v2.10.16/argocd-test.html +++ b/docs/snyk/v2.10.18/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:28:59 am (UTC+00:00)

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

    Snyk test report

    -
    7 known vulnerabilities
    -
    163 vulnerable dependency paths
    +
    10 known vulnerabilities
    +
    171 vulnerable dependency paths
    2042 dependencies
    @@ -3141,7 +3141,7 @@

    References

    -

    Regular Expression Denial of Service (ReDoS)

    +

    LGPL-3.0 license

    @@ -3152,21 +3152,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 + gopkg.in/retry.v1
    • 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/Azure/kubelogin/pkg/token@0.0.20 and others
    @@ -3178,39 +3178,11 @@

    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 + github.com/argoproj/argo-cd/v2@0.0.0 - react-router@4.3.1 + github.com/Azure/kubelogin/pkg/token@0.0.20 - path-to-regexp@1.8.0 + gopkg.in/retry.v1@1.0.3 @@ -3221,89 +3193,12 @@

      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

      - +

      LGPL-3.0 license


    @@ -3613,7 +3508,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

    • @@ -3635,7 +3530,7 @@

      References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -3652,14 +3547,136 @@

    Insertion of Sensitive Information into Log File

    Package Manager: golang
  • - Vulnerable module: + 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

    + +
    + + + +
    +
    +

    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 + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.7
    @@ -3674,7 +3691,7 @@

    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-retryablehttp@0.7.7 @@ -3685,7 +3702,7 @@

    Detailed paths

    github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3696,7 +3713,7 @@

    Detailed paths

    github.com/xanzy/go-gitlab@0.91.1 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3709,7 +3726,7 @@

    Detailed paths

    github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3722,7 +3739,7 @@

    Detailed paths

    github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3735,7 +3752,7 @@

    Detailed paths

    github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3750,7 +3767,7 @@

    Detailed paths

    github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3765,7 +3782,7 @@

    Detailed paths

    github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3780,7 +3797,7 @@

    Detailed paths

    github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3795,7 +3812,7 @@

    Detailed paths

    github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3812,7 +3829,7 @@

    Detailed paths

    github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3829,7 +3846,7 @@

    Detailed paths

    github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - github.com/hashicorp/go-retryablehttp@0.7.4 + github.com/hashicorp/go-retryablehttp@0.7.7 @@ -3840,25 +3857,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


    -

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

    +

    MPL-2.0 license

    @@ -3875,15 +3884,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/hashicorp/go-cleanhttp
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.7 and others
  • @@ -3897,9 +3906,120 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/Azure/kubelogin/pkg/token@0.0.20 + github.com/hashicorp/go-retryablehttp@0.7.7 - github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.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.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@#84b9f7913604 + + 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@#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.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@#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.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@#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.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@#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.7 + + github.com/hashicorp/go-cleanhttp@0.5.2 @@ -3910,46 +4030,77 @@

    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


    + +
  • +
    +

    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

    + +
    + +
    -

    Template Injection

    +

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

    @@ -3960,21 +4111,21 @@

    Template Injection

    • - 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: - dompurify + github.com/Azure/azure-sdk-for-go/sdk/azidentity
    • Introduced through: - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others
    @@ -3986,11 +4137,11 @@

    Detailed paths

    • Introduced through: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 - redoc@2.0.0-rc.64 + github.com/Azure/kubelogin/pkg/token@0.0.20 - dompurify@2.3.6 + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 @@ -4002,24 +4153,40 @@

      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.

      -

      PoC

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

      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 dompurify to version 2.4.9, 3.0.11 or higher.

      +

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

      References


    diff --git a/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.10.18/ghcr.io_dexidp_dex_v2.37.0.html similarity index 77% rename from docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html rename to docs/snyk/v2.10.18/ghcr.io_dexidp_dex_v2.37.0.html index d2889ac440c76..6785149bddaef 100644 --- a/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.10.18/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:29:06 am (UTC+00:00)

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

    Snyk test report

    -
    33 known vulnerabilities
    -
    138 vulnerable dependency paths
    +
    54 known vulnerabilities
    +
    186 vulnerable dependency paths
    786 dependencies
    @@ -909,6 +909,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • @@ -1000,6 +1001,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • @@ -1079,6 +1081,89 @@

    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, by rapidly creating requests and + immediately resetting them. 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

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.37.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.7.0 + +
    • +
    + +
    + + +

    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 + + + +
    • +
    + +
    + +
    + +

    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.

    @@ -1227,7 +1312,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

    • @@ -1369,7 +1454,7 @@

      NVD Description

      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 + authenticate empty data entries as associated data can be misled 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 @@ -2276,7 +2361,7 @@

      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.

      +

      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

      @@ -2362,6 +2447,7 @@

      Remediation

      References

      @@ -2433,7 +2519,7 @@

      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.

      +

      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

      @@ -2451,87 +2537,6 @@

      References

      More about this vulnerability

    -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.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.7.0 - -
    • -
    - -
    - - -

    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 - - - -
    • -
    - -
    - -
    - -

    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

    - - -
    - - -

    Cross-site Scripting (XSS)

    @@ -2747,7 +2752,7 @@

    References

  • Google Groups Forum
  • Jenkins Advisory
  • Security Release
  • -
  • Nuclei Templates
  • +
  • Nuclei Templates

  • @@ -2758,7 +2763,7 @@

    References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -2775,14 +2780,14 @@

    Insertion of Sensitive Information into Log File

    Package Manager: golang
  • - Vulnerable module: + Module: - github.com/hashicorp/go-retryablehttp + github.com/hashicorp/vault/sdk/helper/certutil
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0
  • @@ -2797,7 +2802,79 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/go-retryablehttp@v0.7.1 + 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/consts@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 + + + +
  • +
  • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/physical@v0.5.0 + + + +
  • +
  • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/physical/inmem@v0.5.0 @@ -2808,25 +2885,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 +2906,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.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/go-jose/go-jose/v3 + github.com/hashicorp/vault/api
    • Introduced through: - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0
    @@ -2863,9 +2932,9 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + github.com/hairyhenderson/gomplate/v3@* - github.com/go-jose/go-jose/v3@v3.0.0 + github.com/hashicorp/vault/api@v1.6.0 @@ -2876,14 +2945,1339 @@

      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

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.37.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.37.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.37.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/parser@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/strconv@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/token@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/json/parser@v1.0.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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.37.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

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate +
    • +
    • + Package Manager: golang +
    • +
    • + 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 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: ghcr.io/dexidp/dex:v2.37.0/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.7.1 + +
    • +
    + +
    + + +

    Detailed paths

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

    MPL-2.0 license

    + +
    + + + +
    +
    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    +
    + +
    + medium 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 + + + +
    • +
    + +
    + +
    + +

    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

    + @@ -2959,7 +4353,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

    • @@ -4353,6 +5747,165 @@

      References

    +
    +

    CVE-2024-9143

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    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 + + 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 + + + +
    • +
    • + 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 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    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.11.8/haproxy_2.6.14-alpine.html b/docs/snyk/v2.10.18/haproxy_2.6.14-alpine.html similarity index 92% rename from docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.10.18/haproxy_2.6.14-alpine.html index ce97669944805..33f4c150692e7 100644 --- a/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.10.18/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:29:11 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
    @@ -2733,6 +2733,187 @@

    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.11.8/quay.io_argoproj_argocd_v2.11.8.html b/docs/snyk/v2.10.18/quay.io_argoproj_argocd_v2.10.18.html similarity index 89% rename from docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html rename to docs/snyk/v2.10.18/quay.io_argoproj_argocd_v2.10.18.html index 55093f719c826..be5563568dc76 100644 --- a/docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html +++ b/docs/snyk/v2.10.18/quay.io_argoproj_argocd_v2.10.18.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)

    +

    October 27th 2024, 12:29:29 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.10.18/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.10.18/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.18//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.18/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.18/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    26 known vulnerabilities
    -
    168 vulnerable dependency paths
    -
    2280 dependencies
    +
    30 known vulnerabilities
    +
    176 vulnerable dependency paths
    +
    2278 dependencies
    @@ -492,7 +492,7 @@

    Allocation of Resources Without Limits or Throttling

  • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argo-cd/v2 /usr/local/bin/argocd
  • Package Manager: golang @@ -559,182 +559,6 @@

    References

    More about this vulnerability

  • -
    -
    -

    CVE-2024-41996

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.8 and openssl/libssl3@3.0.2-0ubuntu1.18 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - openssh/openssh-client@1:8.9p1-3ubuntu0.10 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.18 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - 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 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - openssl@3.0.2-0ubuntu1.18 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.18 - - - -
    • -
    - -
    - -
    - -

    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.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - -

    Information Exposure

    @@ -748,7 +572,7 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -761,7 +585,7 @@

      Information Exposure

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and libgcrypt20@1.9.4-3ubuntu3 + docker-image|quay.io/argoproj/argocd@v2.10.18 and libgcrypt20@1.9.4-3ubuntu3
    @@ -774,7 +598,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 libgcrypt20@1.9.4-3ubuntu3 @@ -783,7 +607,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -794,7 +618,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -805,7 +629,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -818,7 +642,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -831,7 +655,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -844,7 +668,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -857,7 +681,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -870,7 +694,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -883,7 +707,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -896,7 +720,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -909,7 +733,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -961,7 +785,7 @@

      CVE-2024-26462

      • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -974,7 +798,7 @@

        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.10.18 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
      @@ -987,7 +811,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libk5crypto3@1.19.2-2ubuntu0.4 @@ -996,7 +820,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -1017,7 +841,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -1040,7 +864,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5-3@1.19.2-2ubuntu0.4 @@ -1049,7 +873,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -1070,7 +894,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -1079,7 +903,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -1090,11 +914,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -1103,11 +927,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 @@ -1118,7 +942,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -1137,7 +961,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -1169,6 +993,66 @@

        References

        More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.18/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

    + +
    + + +

    Denial of Service (DoS)

    @@ -1182,7 +1066,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.10.18/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang @@ -1259,7 +1143,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 +1165,7 @@

        References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -1292,20 +1176,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.10.18/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 +1204,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 +1215,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 +1236,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/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.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1386,11 +1262,9 @@

    Detailed paths

    -

    XML External Entity (XXE) Injection

    +

    MPL-2.0 license

    @@ -1433,21 +1296,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.10.18/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 +1322,9 @@

    Detailed paths

    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1506,21 +1356,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/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 +1382,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 - - git@1:2.34.1-1ubuntu1.11 + helm.sh/helm/v3@* - expat/libexpat1@2.4.7-1ubuntu0.3 + github.com/hashicorp/go-multierror@v1.1.1 @@ -1547,28 +1395,137 @@

      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. nextScaffoldPart in xmlparse.c can have an integer overflow for m_groupSize on 32-bit platforms (where UINT_MAX equals SIZE_MAX).

      -

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 expat.

      -

      References

      - +

      MPL-2.0 license

      + +
      + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.18/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:v2.10.18/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.13.1 + +
    • +
    + +
    + + +

    Detailed paths

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

    MPL-2.0 license


    -

    CVE-2024-8096

    +

    CVE-2023-4039

    @@ -1579,7 +1536,7 @@

    CVE-2024-8096

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -1587,13 +1544,13 @@

      CVE-2024-8096

    • Vulnerable module: - curl/libcurl3-gnutls + gcc-12/libstdc++6
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1605,11 +1562,51 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 - git@1:2.34.1-1ubuntu1.11 + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + apt@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + 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.10.18 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -1621,23 +1618,34 @@

      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. +

      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.

      -

      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.

      +

      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 curl.

      +

      There is no fixed version for Ubuntu:22.04 gcc-12.

      References


    @@ -1653,7 +1661,7 @@

    CVE-2023-7008

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -1666,7 +1674,7 @@

      CVE-2023-7008

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and systemd/libsystemd0@249.11-0ubuntu3.12 + docker-image|quay.io/argoproj/argocd@v2.10.18 and systemd/libsystemd0@249.11-0ubuntu3.12
    @@ -1679,7 +1687,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1688,7 +1696,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -1699,7 +1707,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps/libprocps8@2:3.3.17-6ubuntu2.1 @@ -1710,7 +1718,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 util-linux@2.37.2-4ubuntu3.4 @@ -1721,7 +1729,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 util-linux/bsdutils@1:2.37.2-4ubuntu3.4 @@ -1732,7 +1740,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -1745,7 +1753,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 systemd/libudev1@249.11-0ubuntu3.12 @@ -1754,7 +1762,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 libfido2/libfido2-1@1.10.0-1 @@ -1765,7 +1773,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 util-linux@2.37.2-4ubuntu3.4 @@ -1776,7 +1784,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -1831,7 +1839,7 @@

      Arbitrary Code Injection

      • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -1844,7 +1852,7 @@

        Arbitrary Code Injection

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and shadow/passwd@1:4.8.1-2ubuntu2.2 + docker-image|quay.io/argoproj/argocd@v2.10.18 and shadow/passwd@1:4.8.1-2ubuntu2.2
      @@ -1857,7 +1865,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 shadow/passwd@1:4.8.1-2ubuntu2.2 @@ -1866,7 +1874,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -1877,7 +1885,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -1888,7 +1896,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 shadow/login@1:4.8.1-2ubuntu2.2 @@ -1935,7 +1943,7 @@

        Uncontrolled Recursion

        • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -1948,7 +1956,7 @@

          Uncontrolled Recursion

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.10.18 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
        @@ -1961,7 +1969,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 @@ -1970,7 +1978,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 grep@3.7-1build1 @@ -2010,6 +2018,77 @@

          References

          More about this vulnerability

    +
    +
    +

    Integer Overflow or Wraparound

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + pcre2/libpcre2-8-0 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.10.18 and pcre2/libpcre2-8-0@10.39-3ubuntu0.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + pcre2/libpcre2-8-0@10.39-3ubuntu0.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Integer overflow vulnerability in pcre2test before 10.41 allows attackers to cause a denial of service or other unspecified impacts via negative input.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 pcre2.

    +

    References

    + + +
    + + +

    Release of Invalid Pointer or Reference

    @@ -2023,7 +2102,7 @@

    Release of Invalid Pointer or Reference

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2036,7 +2115,7 @@

      Release of Invalid Pointer or Reference

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.10.18 and patch@2.7.6-7build2
    @@ -2049,7 +2128,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 patch@2.7.6-7build2 @@ -2093,7 +2172,7 @@

      Double Free

      • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -2106,7 +2185,7 @@

        Double Free

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.10.18 and patch@2.7.6-7build2
      @@ -2119,7 +2198,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 patch@2.7.6-7build2 @@ -2155,6 +2234,182 @@

        References

        More about this vulnerability

    +
    +
    +

    CVE-2024-41996

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.10.18 and openssl/libssl3@3.0.2-0ubuntu1.18 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + ca-certificates@20240203~22.04.1 + + openssl@3.0.2-0ubuntu1.18 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + 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 + + openssl/libssl3@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + openssl@3.0.2-0ubuntu1.18 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.18 + + ca-certificates@20240203~22.04.1 + + openssl@3.0.2-0ubuntu1.18 + + + +
    • +
    + +
    + +
    + +

    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.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + +

    CVE-2023-50495

    @@ -2168,7 +2423,7 @@

    CVE-2023-50495

    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2181,7 +2436,7 @@

      CVE-2023-50495

    • 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.10.18 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -2194,7 +2449,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -2203,7 +2458,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 bash@5.1-6ubuntu1.1 @@ -2214,7 +2469,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -2225,7 +2480,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 less@590-1ubuntu0.22.04.3 @@ -2236,7 +2491,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 libedit/libedit2@3.1-20210910-1build1 @@ -2247,7 +2502,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -2258,7 +2513,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -2269,7 +2524,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2280,7 +2535,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 util-linux@2.37.2-4ubuntu3.4 @@ -2291,7 +2546,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -2306,7 +2561,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -2321,7 +2576,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -2330,7 +2585,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2341,7 +2596,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -2356,7 +2611,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -2365,7 +2620,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2376,7 +2631,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -2385,7 +2640,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -2432,7 +2687,7 @@

      CVE-2023-45918

      • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -2445,7 +2700,7 @@

        CVE-2023-45918

      • 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.10.18 and ncurses/libtinfo6@6.3-2ubuntu0.1
      @@ -2458,7 +2713,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -2467,7 +2722,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 bash@5.1-6ubuntu1.1 @@ -2478,7 +2733,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -2489,7 +2744,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 less@590-1ubuntu0.22.04.3 @@ -2500,7 +2755,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 libedit/libedit2@3.1-20210910-1build1 @@ -2511,7 +2766,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -2522,7 +2777,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -2533,7 +2788,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2544,7 +2799,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 util-linux@2.37.2-4ubuntu3.4 @@ -2555,7 +2810,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -2570,7 +2825,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -2585,7 +2840,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -2594,7 +2849,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2605,7 +2860,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -2620,7 +2875,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -2629,7 +2884,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 procps@2:3.3.17-6ubuntu2.1 @@ -2640,7 +2895,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -2649,7 +2904,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -2694,7 +2949,7 @@

        Resource Exhaustion

        • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -2707,7 +2962,7 @@

          Resource Exhaustion

        • 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.10.18 and libzstd/libzstd1@1.4.8+dfsg-3build1
        @@ -2720,7 +2975,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 libzstd/libzstd1@1.4.8+dfsg-3build1 @@ -2771,7 +3026,7 @@

          Integer Overflow or Wraparound

          • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -2784,7 +3039,7 @@

            Integer Overflow or Wraparound

          • 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.10.18 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
          @@ -2797,7 +3052,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libk5crypto3@1.19.2-2ubuntu0.4 @@ -2806,7 +3061,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -2827,7 +3082,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -2850,7 +3105,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5-3@1.19.2-2ubuntu0.4 @@ -2859,7 +3114,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -2880,7 +3135,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -2889,7 +3144,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -2900,11 +3155,11 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -2913,11 +3168,11 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 @@ -2928,7 +3183,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -2947,7 +3202,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -2995,7 +3250,7 @@

            CVE-2024-26461

            • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:22.04 @@ -3008,7 +3263,7 @@

              CVE-2024-26461

            • 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.10.18 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
            @@ -3021,7 +3276,7 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libk5crypto3@1.19.2-2ubuntu0.4 @@ -3030,7 +3285,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3051,7 +3306,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3074,7 +3329,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5-3@1.19.2-2ubuntu0.4 @@ -3083,7 +3338,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3104,7 +3359,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -3113,7 +3368,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -3124,11 +3379,11 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -3137,11 +3392,11 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 @@ -3152,7 +3407,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3171,7 +3426,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -3216,7 +3471,7 @@

              CVE-2024-26458

              • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
              • Package Manager: ubuntu:22.04 @@ -3229,7 +3484,7 @@

                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.10.18 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
              @@ -3242,7 +3497,7 @@

              Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libk5crypto3@1.19.2-2ubuntu0.4 @@ -3251,7 +3506,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3272,7 +3527,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3295,7 +3550,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5-3@1.19.2-2ubuntu0.4 @@ -3304,7 +3559,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3325,7 +3580,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -3334,7 +3589,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 openssh/openssh-client@1:8.9p1-3ubuntu0.10 @@ -3345,11 +3600,11 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 @@ -3358,11 +3613,11 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 @@ -3373,7 +3628,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 adduser@3.118ubuntu5 @@ -3392,7 +3647,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -3437,7 +3692,7 @@

                Out-of-bounds Write

                • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -3450,7 +3705,7 @@

                  Out-of-bounds Write

                • 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.10.18 and gnupg2/gpgv@2.2.27-3ubuntu2.1
                @@ -3463,7 +3718,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -3472,7 +3727,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -3483,7 +3738,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3494,7 +3749,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3505,7 +3760,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3516,7 +3771,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3529,7 +3784,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3542,7 +3797,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3551,7 +3806,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3562,7 +3817,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3575,7 +3830,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 @@ -3584,7 +3839,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3595,7 +3850,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 @@ -3604,7 +3859,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3615,7 +3870,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3624,7 +3879,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3635,7 +3890,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3648,7 +3903,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3661,7 +3916,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg-agent@2.2.27-3ubuntu2.1 @@ -3670,7 +3925,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3681,7 +3936,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3694,7 +3949,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3707,7 +3962,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 @@ -3716,7 +3971,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3727,7 +3982,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 @@ -3736,7 +3991,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3747,7 +4002,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gpgsm@2.2.27-3ubuntu2.1 @@ -3756,7 +4011,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3767,7 +4022,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3816,7 +4071,7 @@

                  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.10.18/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -3829,7 +4084,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.10.18 and glibc/libc-bin@2.35-0ubuntu3.8
                @@ -3842,7 +4097,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 glibc/libc-bin@2.35-0ubuntu3.8 @@ -3851,7 +4106,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 glibc/libc6@2.35-0ubuntu3.8 @@ -3897,7 +4152,7 @@

                  Improper Input Validation

                  • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
                  • Package Manager: ubuntu:22.04 @@ -3911,7 +4166,7 @@

                    Improper Input Validation

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others + docker-image|quay.io/argoproj/argocd@v2.10.18, git@1:2.34.1-1ubuntu1.11 and others
                  @@ -3923,7 +4178,7 @@

                  Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 @@ -3934,7 +4189,7 @@

                    Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git@1:2.34.1-1ubuntu1.11 @@ -3943,7 +4198,7 @@

                    Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 git-lfs@3.0.2-1ubuntu0.2 @@ -3990,7 +4245,7 @@

                    Uncontrolled Recursion

                    • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
                    • Package Manager: ubuntu:22.04 @@ -4003,7 +4258,7 @@

                      Uncontrolled Recursion

                    • 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.10.18 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
                    @@ -4016,7 +4271,7 @@

                    Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4025,7 +4280,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -4036,7 +4291,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 apt@2.4.13 @@ -4049,7 +4304,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 @@ -4058,7 +4313,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -4105,7 +4360,7 @@

                      Improper Input Validation

                      • - Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.18/argoproj/argocd Dockerfile
                      • Package Manager: ubuntu:22.04 @@ -4118,7 +4373,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.10.18 and coreutils@8.32-4.1ubuntu1.2
                      @@ -4131,7 +4386,7 @@

                      Detailed paths

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.8 + docker-image|quay.io/argoproj/argocd@v2.10.18 coreutils@8.32-4.1ubuntu1.2 diff --git a/docs/snyk/v2.10.16/redis_7.0.15-alpine.html b/docs/snyk/v2.10.18/redis_7.0.15-alpine.html similarity index 53% rename from docs/snyk/v2.10.16/redis_7.0.15-alpine.html rename to docs/snyk/v2.10.18/redis_7.0.15-alpine.html index dace95d6e4de1..4f1b8e1ba380f 100644 --- a/docs/snyk/v2.10.16/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.10.18/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)

                        +

                        October 27th 2024, 12:29:33 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,189 @@

    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.11.11/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.11.8/argocd-iac-install.html rename to docs/snyk/v2.11.11/argocd-iac-install.html index d1f9777c282dd..761f07388bc9f 100644 --- a/docs/snyk/v2.11.8/argocd-iac-install.html +++ b/docs/snyk/v2.11.11/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:28:36 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.11.8/argocd-iac-namespace-install.html b/docs/snyk/v2.11.11/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.11/argocd-iac-namespace-install.html index 712325c01faa0..5c2d4683d3f45 100644 --- a/docs/snyk/v2.11.8/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.11.11/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:28:45 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.11.8/argocd-test.html b/docs/snyk/v2.11.11/argocd-test.html similarity index 88% rename from docs/snyk/v2.11.8/argocd-test.html rename to docs/snyk/v2.11.11/argocd-test.html index c47bbee9440bb..7956765bd03e6 100644 --- a/docs/snyk/v2.11.8/argocd-test.html +++ b/docs/snyk/v2.11.11/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:26:42 am (UTC+00:00)

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

    Snyk test report

    -
    6 known vulnerabilities
    -
    157 vulnerable dependency paths
    +
    10 known vulnerabilities
    +
    177 vulnerable dependency paths
    2041 dependencies
    @@ -3141,7 +3141,7 @@

    References

    -

    Regular Expression Denial of Service (ReDoS)

    +

    LGPL-3.0 license

    @@ -3152,21 +3152,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 + gopkg.in/retry.v1
    • 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/Azure/kubelogin/pkg/token@0.0.20 and others
    @@ -3178,39 +3178,11 @@

    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 + github.com/argoproj/argo-cd/v2@0.0.0 - react-router@4.3.1 + github.com/Azure/kubelogin/pkg/token@0.0.20 - path-to-regexp@1.8.0 + gopkg.in/retry.v1@1.0.3 @@ -3221,89 +3193,12 @@

      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

      - +

      LGPL-3.0 license


    @@ -3398,7 +3293,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:

    +
    +
    +

    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

    @@ -3643,7 +3660,7 @@

    References

    -

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

    +

    MPL-2.0 license

    @@ -3660,15 +3677,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/hashicorp/go-retryablehttp
  • Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others
  • @@ -3682,129 +3699,502 @@

    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/hashicorp/go-retryablehttp@0.7.4 - - -
    - -
    - -

    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: + 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: - argo-cd-ui@1.0.0 + github.com/argoproj/argo-cd/v2@0.0.0 - redoc@2.0.0-rc.64 + github.com/xanzy/go-gitlab@0.91.1 - dompurify@2.3.6 + 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

    -

    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)> ]]>
    -        
    +

    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 dompurify to version 2.4.9, 3.0.11 or higher.

    +

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

    References


    diff --git a/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.11.11/ghcr.io_dexidp_dex_v2.38.0.html similarity index 66% rename from docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.11.11/ghcr.io_dexidp_dex_v2.38.0.html index 3c557de6a1064..a437658d2807c 100644 --- a/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.11.11/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)

    +

    October 27th 2024, 12:26:49 am (UTC+00:00)

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

    Snyk test report

    -
    18 known vulnerabilities
    -
    85 vulnerable dependency paths
    +
    39 known vulnerabilities
    +
    127 vulnerable dependency paths
    829 dependencies
    @@ -941,7 +941,7 @@

    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.

    +

    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

    @@ -1018,6 +1018,7 @@

    Remediation

    References

    @@ -1089,7 +1090,7 @@

    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.

    +

    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

    @@ -1107,6 +1108,852 @@

    References

    More about this vulnerability

    +
    +
    +

    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

    @@ -1126,14 +1973,391 @@

    Insertion of Sensitive Information into Log File

    Package Manager: golang
  • - Vulnerable module: + 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

    + +
    + + + +
    +
    +

    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 + github.com/hashicorp/consul/api
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -1148,7 +2372,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hashicorp/consul/api@v1.13.0 @@ -1159,20 +2383,132 @@

    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


    + +
    +
    +

    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/gosimple/slug +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0 + +
    • +
    + +
    + + +

    Detailed paths

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

    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/go-sql-driver/mysql +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1 + +
    • +
    + +
    + + +

    Detailed paths

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

    MPL-2.0 license

    + +
    + +
    @@ -2620,6 +3956,165 @@

    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.11/haproxy_2.6.14-alpine.html similarity index 92% rename from docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.11.11/haproxy_2.6.14-alpine.html index bb20c3cb21a3c..2e9d32660860f 100644 --- a/docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.11.11/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)

    +

    October 27th 2024, 12:26:54 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
    @@ -2733,6 +2733,187 @@

    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.11/quay.io_argoproj_argocd_v2.11.11.html similarity index 69% rename from docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html rename to docs/snyk/v2.11.11/quay.io_argoproj_argocd_v2.11.11.html index 92b035cf413d0..3469c46d89d39 100644 --- a/docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html +++ b/docs/snyk/v2.11.11/quay.io_argoproj_argocd_v2.11.11.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)

    +

    October 27th 2024, 12:27:12 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.11/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.11.11/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.11//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.11/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.11/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    34 known vulnerabilities
    -
    236 vulnerable dependency paths
    -
    2278 dependencies
    +
    31 known vulnerabilities
    +
    177 vulnerable dependency paths
    +
    2280 dependencies
    @@ -492,7 +492,7 @@

    Allocation of Resources Without Limits or Throttling

  • - 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.11/argoproj/argo-cd/v2 /usr/local/bin/argocd
  • Package Manager: golang @@ -561,7 +561,7 @@

    References

    -

    CVE-2024-41996

    +

    Information Exposure

    @@ -572,7 +572,7 @@

    CVE-2024-41996

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -580,12 +580,12 @@

      CVE-2024-41996

    • Vulnerable module: - openssl/libssl3 + libgcrypt20
    • 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.11 and libgcrypt20@1.9.4-3ubuntu3
    @@ -598,113 +598,150 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + gnupg2/dirmngr@2.2.27-3ubuntu2.1 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - libfido2/libfido2-1@1.10.0-1 + gnupg2/gpg@2.2.27-3ubuntu2.1 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssh/openssh-client@1:8.9p1-3ubuntu0.10 + apt@2.4.13 - openssl/libssl3@3.0.2-0ubuntu1.16 + apt/libapt-pkg6.0@2.4.13 + + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - ca-certificates@20230311ubuntu0.22.04.1 + apt@2.4.13 - openssl@3.0.2-0ubuntu1.16 + gnupg2/gpgv@2.2.27-3ubuntu2.1 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - git@1:2.34.1-1ubuntu1.11 + gnupg2/gpg@2.2.27-3ubuntu2.1 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + gnupg2/gpgconf@2.2.27-3ubuntu2.1 - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - adduser@3.118ubuntu5 + gnupg2/gnupg@2.2.27-3ubuntu2.1 - shadow/passwd@1:4.8.1-2ubuntu2.2 + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - pam/libpam-modules@1.4.0-11ubuntu2.4 + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 - libnsl/libnsl2@1.3.0-2build2 + gnupg2/gnupg@2.2.27-3ubuntu2.1 - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + libgcrypt20@1.9.4-3ubuntu3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 - openssl/libssl3@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpgsm@2.2.27-3ubuntu2.1 - openssl@3.0.2-0ubuntu1.16 + libgcrypt20@1.9.4-3ubuntu3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - ca-certificates@20230311ubuntu0.22.04.1 + apt@2.4.13 - openssl@3.0.2-0ubuntu1.16 + apt/libapt-pkg6.0@2.4.13 + + systemd/libsystemd0@249.11-0ubuntu3.12 + + libgcrypt20@1.9.4-3ubuntu3 @@ -716,28 +753,28 @@

      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 libgcrypt20 package and not the libgcrypt20 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.

      +

      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 openssl.

      +

      There is no fixed version for Ubuntu:22.04 libgcrypt20.

      References


    -

    CVE-2024-6119

    +

    CVE-2024-26462

    @@ -748,7 +785,7 @@

    CVE-2024-6119

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -756,12 +793,12 @@

      CVE-2024-6119

    • Vulnerable module: - openssl/libssl3 + krb5/libk5crypto3
    • 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.11 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
    @@ -774,77 +811,138 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl/libssl3@3.0.2-0ubuntu1.16 + 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.11 - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + 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/libssl3@3.0.2-0ubuntu1.16 + 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.11 - libfido2/libfido2-1@1.10.0-1 + 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.11 + + krb5/libkrb5-3@1.19.2-2ubuntu0.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 - openssl/libssl3@3.0.2-0ubuntu1.16 + 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 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + 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.11 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.16 + 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.11 - ca-certificates@20230311ubuntu0.22.04.1 + git@1:2.34.1-1ubuntu1.11 - openssl@3.0.2-0ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.18 - openssl/libssl3@3.0.2-0ubuntu1.16 + 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.11 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 + 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.11 adduser@3.118ubuntu5 @@ -856,31 +954,16 @@

      Detailed paths

      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 + 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.11 - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.16 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -892,48 +975,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 krb5 package and not the krb5 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.

      +

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/kdc/ndr.c.

      Remediation

      -

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.18 or higher.

      +

      There is no fixed version for Ubuntu:22.04 krb5.

      References


    -

    Information Exposure

    +

    LGPL-3.0 license

    @@ -944,20 +1006,20 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - libgcrypt20 + gopkg.in/retry.v1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and libgcrypt20@1.9.4-3ubuntu3 + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3
    @@ -970,885 +1032,69 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + github.com/argoproj/argo-cd/v2@* - libgcrypt20@1.9.4-3ubuntu3 + gopkg.in/retry.v1@v1.0.3
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - libgcrypt20@1.9.4-3ubuntu3 - - +
    + +

    LGPL-3.0 license

    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - apt@2.4.12 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - +
    -
  • + + + +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.11/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: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 + github.com/argoproj/argo-cd/v2@* - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - 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.10.16 - - 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.10.16 - - 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.10.16 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpgsm@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    - -
    - -
    - -

    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.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 libgcrypt20.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-26462

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 - -
    • -
    - -
    - - -

    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 - - 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.

    -

    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.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-37371

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 - -
    • -
    - -
    - - -

    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 - - 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 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

    - - -
    - - - -
    -
    -

    CVE-2024-37370

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 - -
    • -
    - -
    - - -

    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 - - 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 + github.com/rs/cors@v1.9.0 @@ -1897,7 +1143,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 +1165,7 @@

        References

    -

    Insertion of Sensitive Information into Log File

    +

    MPL-2.0 license

    @@ -1930,20 +1176,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.11/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,150 +1204,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - github.com/hashicorp/go-retryablehttp@v0.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

    - - -
    - - - -
    -
    -

    Integer Overflow or Wraparound

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - expat/libexpat1 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - git@1:2.34.1-1ubuntu1.11 - - expat/libexpat1@2.4.7-1ubuntu0.3 - - - -
    • -
    - -
    - -
    - -

    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. dtdCopy in xmlparse.c can have an integer overflow for nDefaultAtts on 32-bit platforms (where UINT_MAX equals SIZE_MAX).

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 expat.

    -

    References

    - - -
    - - - -
    -
    -

    XML External Entity (XXE) Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - expat/libexpat1 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -2144,21 +1236,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.11/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
    @@ -2170,11 +1262,9 @@

    Detailed paths

    -

    Out-of-bounds Read

    +

    Insertion of Sensitive Information into Log File

    @@ -2217,21 +1296,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.11/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • Vulnerable module: - curl/libcurl3-gnutls + 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
    @@ -2243,11 +1322,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-retryablehttp@v0.7.4 @@ -2258,37 +1335,25 @@

      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.

      -

      libcurl's ASN1 parser code has the GTime2str() function, used for parsing an - ASN.1 Generalized Time field. If given an syntactically incorrect field, the - parser might end up using -1 for the length of the time fraction, leading to - a strlen() getting performed on a pointer to a heap buffer area that is not - (purposely) null terminated.

      -

      This flaw most likely leads to a crash, but can also lead to heap contents - getting returned to the application when - CURLINFO_CERTINFO is used.

      +

      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 Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.17 or higher.

      +

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

      References


    -

    CVE-2024-8096

    +

    MPL-2.0 license

    @@ -2299,21 +1364,21 @@

    CVE-2024-8096

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/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-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
    @@ -2325,11 +1390,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-retryablehttp@v0.7.4 @@ -2340,53 +1403,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.11/helm/v3 /usr/local/bin/helm
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - systemd/libsystemd0 + github.com/hashicorp/go-multierror
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and systemd/libsystemd0@249.11-0ubuntu3.12 + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1
    @@ -2399,110 +1450,9 @@

    Detailed paths

    -
    -

    Arbitrary Code Injection

    +
    +

    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.11/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - shadow/passwd + github.com/hashicorp/go-cleanhttp
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and shadow/passwd@1:4.8.1-2ubuntu2.2 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2
    @@ -2577,40 +1510,9 @@

    Detailed paths

    -
    -

    Uncontrolled Recursion

    +
    +

    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.11/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - pcre3/libpcre3 + github.com/gosimple/slug
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
    @@ -2681,20 +1570,9 @@

    Detailed paths

    -
    -

    Release of Invalid Pointer or Reference

    +
    +

    CVE-2023-4039

    -
    - low severity +
    + medium severity

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2751,27 +1612,69 @@

      Release of Invalid Pointer or Reference

    • Vulnerable module: - patch + gcc-12/libstdc++6
    • 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.11 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    -
    +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + apt@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + apt@2.4.13 + + apt/libapt-pkg6.0@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + -

      Detailed paths

      +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.11 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + -
        +
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - patch@2.7.6-7build2 + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -2783,26 +1686,39 @@

        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. +

        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.

        -

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

        +

        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 patch.

        +

        There is no fixed version for Ubuntu:22.04 gcc-12.

        References


    -

    Double Free

    +

    CVE-2023-7008

    @@ -2813,7 +1729,7 @@

    Double Free

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2821,12 +1737,12 @@

      Double Free

    • Vulnerable module: - patch + systemd/libsystemd0
    • 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.11 and systemd/libsystemd0@249.11-0ubuntu3.12
    @@ -2839,9 +1755,110 @@

    Detailed paths

    -

    CVE-2024-2511

    +

    Arbitrary Code Injection

    @@ -2888,7 +1907,7 @@

    CVE-2024-2511

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2896,12 +1915,12 @@

      CVE-2024-2511

    • Vulnerable module: - openssl/libssl3 + shadow/passwd
    • 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.11 and shadow/passwd@1:4.8.1-2ubuntu2.2
    @@ -2914,113 +1933,124 @@

    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 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl/libssl3@3.0.2-0ubuntu1.16 + shadow/passwd@1:4.8.1-2ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - libfido2/libfido2-1@1.10.0-1 + adduser@3.118ubuntu5 - openssl/libssl3@3.0.2-0ubuntu1.16 + shadow/passwd@1:4.8.1-2ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.16 + shadow/passwd@1:4.8.1-2ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - ca-certificates@20230311ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl@3.0.2-0ubuntu1.16 - - openssl/libssl3@3.0.2-0ubuntu1.16 + shadow/login@1:4.8.1-2ubuntu2.2
    • -
    • - 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 - - +
  • + +
    + +

    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.11/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + pcre3/libpcre3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.11 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + +
    • +
    - +
    + + +

    Detailed paths

    + +
    -

    CVE-2024-4603

    +

    Integer Overflow or Wraparound

    @@ -3082,7 +2099,7 @@

    CVE-2024-4603

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3090,12 +2107,12 @@

      CVE-2024-4603

    • Vulnerable module: - openssl/libssl3 + pcre2/libpcre2-8-0
    • 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.11 and pcre2/libpcre2-8-0@10.39-3ubuntu0.1
    @@ -3108,113 +2125,9 @@

    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 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl@3.0.2-0ubuntu1.16 + pcre2/libpcre2-8-0@10.39-3ubuntu0.1 @@ -3226,54 +2139,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 pcre2 package and not the pcre2 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.

      +

      Integer overflow vulnerability in pcre2test before 10.41 allows attackers to cause a denial of service or other unspecified impacts via negative input.

      Remediation

      -

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.17 or higher.

      +

      There is no fixed version for Ubuntu:22.04 pcre2.

      References


    -

    CVE-2024-4741

    +

    Release of Invalid Pointer or Reference

    @@ -3284,7 +2170,7 @@

    CVE-2024-4741

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3292,12 +2178,12 @@

      CVE-2024-4741

    • Vulnerable module: - openssl/libssl3 + patch
    • 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.11 and patch@2.7.6-7build2
    @@ -3310,113 +2196,79 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - openssl/libssl3@3.0.2-0ubuntu1.16 + patch@2.7.6-7build2
    • -
    • - 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 - - +
    + +

    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

    + -
  • -
  • - 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 - - +
  • +
    +

    Double Free

    +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 - - openssl@3.0.2-0ubuntu1.16 - - +
    + low severity +
    -
  • +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.11.11 and patch@2.7.6-7build2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    -

    CVE-2024-5535

    +

    CVE-2024-41996

    @@ -3455,7 +2315,7 @@

    CVE-2024-5535

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3468,7 +2328,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.11 and openssl/libssl3@3.0.2-0ubuntu1.18
    @@ -3481,77 +2341,77 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - 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.11 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.11 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.11 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.11 - 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.11 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.11 adduser@3.118ubuntu5 @@ -3563,31 +2423,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.11 - 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.11 - 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 +2461,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 +2491,7 @@

    CVE-2023-50495

    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -3705,7 +2504,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.11 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -3718,7 +2517,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -3727,7 +2526,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 bash@5.1-6ubuntu1.1 @@ -3738,7 +2537,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -3749,7 +2548,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 less@590-1ubuntu0.22.04.3 @@ -3760,7 +2559,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 libedit/libedit2@3.1-20210910-1build1 @@ -3771,7 +2570,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -3782,7 +2581,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -3793,7 +2592,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -3804,7 +2603,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 util-linux@2.37.2-4ubuntu3.4 @@ -3815,7 +2614,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3830,7 +2629,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3845,7 +2644,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -3854,7 +2653,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -3865,7 +2664,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3880,7 +2679,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -3889,7 +2688,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -3900,7 +2699,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -3909,7 +2708,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -3956,7 +2755,7 @@

      CVE-2023-45918

      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -3969,7 +2768,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.11 and ncurses/libtinfo6@6.3-2ubuntu0.1
      @@ -3982,7 +2781,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libtinfo6@6.3-2ubuntu0.1 @@ -3991,7 +2790,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 bash@5.1-6ubuntu1.1 @@ -4002,7 +2801,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -4013,7 +2812,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 less@590-1ubuntu0.22.04.3 @@ -4024,7 +2823,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 libedit/libedit2@3.1-20210910-1build1 @@ -4035,7 +2834,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -4046,7 +2845,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -4057,7 +2856,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -4068,7 +2867,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 util-linux@2.37.2-4ubuntu3.4 @@ -4079,7 +2878,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -4094,7 +2893,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4109,7 +2908,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncursesw6@6.3-2ubuntu0.1 @@ -4118,7 +2917,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -4129,7 +2928,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4144,7 +2943,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/libncurses6@6.3-2ubuntu0.1 @@ -4153,7 +2952,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 procps@2:3.3.17-6ubuntu2.1 @@ -4164,7 +2963,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-base@6.3-2ubuntu0.1 @@ -4173,7 +2972,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 ncurses/ncurses-bin@6.3-2ubuntu0.1 @@ -4218,7 +3017,7 @@

        Resource Exhaustion

        • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -4231,7 +3030,7 @@

          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.11 and libzstd/libzstd1@1.4.8+dfsg-3build1
        @@ -4244,7 +3043,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 libzstd/libzstd1@1.4.8+dfsg-3build1 @@ -4295,7 +3094,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.11/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -4308,7 +3107,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.11 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
          @@ -4321,16 +3120,16 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - 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.11 adduser@3.118ubuntu5 @@ -4342,16 +3141,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.11 adduser@3.118ubuntu5 @@ -4363,27 +3162,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.11 - 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.11 adduser@3.118ubuntu5 @@ -4395,64 +3194,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.11 - 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.11 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.11 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.11 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.11 adduser@3.118ubuntu5 @@ -4464,16 +3263,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.11 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4519,7 +3318,7 @@

            CVE-2024-26461

            • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:22.04 @@ -4532,7 +3331,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.11 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
            @@ -4545,16 +3344,16 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - 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.11 adduser@3.118ubuntu5 @@ -4566,16 +3365,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.11 adduser@3.118ubuntu5 @@ -4587,27 +3386,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.11 - 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.11 adduser@3.118ubuntu5 @@ -4619,64 +3418,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.11 - 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.11 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.11 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.11 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.11 adduser@3.118ubuntu5 @@ -4688,16 +3487,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.11 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4740,7 +3539,7 @@

              CVE-2024-26458

              • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
              • Package Manager: ubuntu:22.04 @@ -4753,7 +3552,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.11 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
              @@ -4766,16 +3565,16 @@

              Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - 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.11 adduser@3.118ubuntu5 @@ -4787,16 +3586,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.11 adduser@3.118ubuntu5 @@ -4808,27 +3607,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.11 - 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.11 adduser@3.118ubuntu5 @@ -4840,64 +3639,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.11 - 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.11 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.11 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.11 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.11 adduser@3.118ubuntu5 @@ -4909,16 +3708,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.11 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4961,7 +3760,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.11/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -4974,7 +3773,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.11 and gnupg2/gpgv@2.2.27-3ubuntu2.1
                @@ -4987,7 +3786,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -4996,9 +3795,9 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - apt@2.4.12 + apt@2.4.13 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -5007,7 +3806,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5018,7 +3817,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -5029,7 +3828,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -5040,7 +3839,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5053,7 +3852,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5066,7 +3865,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -5075,7 +3874,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5086,7 +3885,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5099,7 +3898,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 @@ -5108,7 +3907,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5119,7 +3918,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 @@ -5128,7 +3927,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5139,7 +3938,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -5148,7 +3947,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5159,7 +3958,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5172,7 +3971,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5185,7 +3984,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg-agent@2.2.27-3ubuntu2.1 @@ -5194,7 +3993,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5205,7 +4004,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5218,7 +4017,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5231,7 +4030,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 @@ -5240,7 +4039,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5251,7 +4050,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 @@ -5260,7 +4059,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5271,7 +4070,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gpgsm@2.2.27-3ubuntu2.1 @@ -5280,7 +4079,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5291,7 +4090,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -5340,7 +4139,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.11/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -5353,7 +4152,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.11 and glibc/libc-bin@2.35-0ubuntu3.8
                @@ -5366,7 +4165,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 glibc/libc-bin@2.35-0ubuntu3.8 @@ -5375,7 +4174,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 glibc/libc6@2.35-0ubuntu3.8 @@ -5421,7 +4220,7 @@

                  Improper Input Validation

                  • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
                  • Package Manager: ubuntu:22.04 @@ -5435,7 +4234,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.11, git@1:2.34.1-1ubuntu1.11 and others
                  @@ -5447,7 +4246,7 @@

                  Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 git@1:2.34.1-1ubuntu1.11 @@ -5458,7 +4257,7 @@

                    Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 git@1:2.34.1-1ubuntu1.11 @@ -5467,7 +4266,7 @@

                    Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 git-lfs@3.0.2-1ubuntu0.2 @@ -5514,7 +4313,7 @@

                    Uncontrolled Recursion

                    • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
                    • Package Manager: ubuntu:22.04 @@ -5527,7 +4326,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.11 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
                    @@ -5540,7 +4339,7 @@

                    Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -5549,9 +4348,9 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - apt@2.4.12 + apt@2.4.13 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -5560,11 +4359,11 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 - 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 +4372,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 @@ -5582,7 +4381,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -5629,7 +4428,7 @@

                      Improper Input Validation

                      • - Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.11/argoproj/argocd Dockerfile
                      • Package Manager: ubuntu:22.04 @@ -5642,7 +4441,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.11 and coreutils@8.32-4.1ubuntu1.2
                      @@ -5655,7 +4454,7 @@

                      Detailed paths

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.16 + docker-image|quay.io/argoproj/argocd@v2.11.11 coreutils@8.32-4.1ubuntu1.2 diff --git a/docs/snyk/v2.11.8/redis_7.0.15-alpine.html b/docs/snyk/v2.11.11/redis_7.0.15-alpine.html similarity index 53% rename from docs/snyk/v2.11.8/redis_7.0.15-alpine.html rename to docs/snyk/v2.11.11/redis_7.0.15-alpine.html index 3f02438fedc1d..2fada676f9022 100644 --- a/docs/snyk/v2.11.8/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.11.11/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)

                        +

                        October 27th 2024, 12:27:16 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,189 @@

    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.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.12.3/argocd-iac-install.html b/docs/snyk/v2.12.6/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.12.3/argocd-iac-install.html rename to docs/snyk/v2.12.6/argocd-iac-install.html index a5698e85b8c0e..eb957b23a1020 100644 --- a/docs/snyk/v2.12.3/argocd-iac-install.html +++ b/docs/snyk/v2.12.6/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:26:17 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.12.3/argocd-iac-namespace-install.html b/docs/snyk/v2.12.6/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.6/argocd-iac-namespace-install.html index 7fbc95ed64a61..f15128bb32236 100644 --- a/docs/snyk/v2.12.3/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.12.6/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:26:26 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.12.6/argocd-test.html b/docs/snyk/v2.12.6/argocd-test.html new file mode 100644 index 0000000000000..0ee95d39cd998 --- /dev/null +++ b/docs/snyk/v2.12.6/argocd-test.html @@ -0,0 +1,1320 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 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)
    • +
    +
    + +
    +
    8 known vulnerabilities
    +
    26 vulnerable dependency paths
    +
    2061 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    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

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.12.6/ghcr.io_dexidp_dex_v2.38.0.html similarity index 66% rename from docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.12.6/ghcr.io_dexidp_dex_v2.38.0.html index af51282d2e037..d86853121cbd4 100644 --- a/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.12.6/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:23:48 am (UTC+00:00)

    +

    October 27th 2024, 12:24:26 am (UTC+00:00)

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

    Snyk test report

    -
    18 known vulnerabilities
    -
    85 vulnerable dependency paths
    +
    39 known vulnerabilities
    +
    127 vulnerable dependency paths
    829 dependencies
    @@ -941,7 +941,7 @@

    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.

    +

    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

    @@ -1018,6 +1018,7 @@

    Remediation

    References

    @@ -1089,7 +1090,7 @@

    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.

    +

    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

    @@ -1107,6 +1108,852 @@

    References

    More about this vulnerability

    +
    +
    +

    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

    @@ -1126,14 +1973,391 @@

    Insertion of Sensitive Information into Log File

    Package Manager: golang
  • - Vulnerable module: + 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

    + +
    + + + +
    +
    +

    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 + github.com/hashicorp/consul/api
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0
    @@ -1148,7 +2372,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/go-retryablehttp@v0.7.1 + github.com/hashicorp/consul/api@v1.13.0 @@ -1159,20 +2383,132 @@

    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


    + +
    +
    +

    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/gosimple/slug +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0 + +
    • +
    + +
    + + +

    Detailed paths

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

    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/go-sql-driver/mysql +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1 + +
    • +
    + +
    + + +

    Detailed paths

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

    MPL-2.0 license

    + +
    + +
    @@ -2620,6 +3956,165 @@

    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.6/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html similarity index 83% rename from docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html rename to docs/snyk/v2.12.6/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html index c072d3a72b314..366c490dc4ac2 100644 --- a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html +++ b/docs/snyk/v2.12.6/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)

    +

    October 27th 2024, 12:24:30 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
    @@ -1297,6 +1297,198 @@

    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.6/public.ecr.aws_docker_library_redis_7.0.15-alpine.html similarity index 53% rename from docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html rename to docs/snyk/v2.12.6/public.ecr.aws_docker_library_redis_7.0.15-alpine.html index da43180e99e7c..c64e552eae6d7 100644 --- a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html +++ b/docs/snyk/v2.12.6/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)

    +

    October 27th 2024, 12:24:35 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,189 @@

    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.12.3/quay.io_argoproj_argocd_v2.12.3.html b/docs/snyk/v2.12.6/quay.io_argoproj_argocd_v2.12.6.html similarity index 82% rename from docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html rename to docs/snyk/v2.12.6/quay.io_argoproj_argocd_v2.12.6.html index ec4329b79d670..4f943f6f1aa00 100644 --- a/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html +++ b/docs/snyk/v2.12.6/quay.io_argoproj_argocd_v2.12.6.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,22 +456,22 @@

    Snyk test report

    -

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

    +

    October 27th 2024, 12:24:52 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.12.6/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.12.6/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.6//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.6/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.6/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    17 known vulnerabilities
    -
    81 vulnerable dependency paths
    +
    19 known vulnerabilities
    +
    73 vulnerable dependency paths
    2292 dependencies
    @@ -481,7 +481,7 @@

    Snyk test report

    -

    CVE-2024-41996

    +

    Information Exposure

    @@ -492,7 +492,7 @@

    CVE-2024-41996

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -500,12 +500,12 @@

      CVE-2024-41996

    • Vulnerable module: - openssl/libssl3t64 + libgcrypt20
    • 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.12.6 and libgcrypt20@1.10.3-2build1
    @@ -518,135 +518,100 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - openssl/libssl3t64@3.0.13-0ubuntu3.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - coreutils@9.4-3ubuntu6 + docker-image|quay.io/argoproj/argocd@v2.12.6 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + gnupg2/dirmngr@2.4.4-2ubuntu17 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - libfido2/libfido2-1@1.14.0-1build3 + gnupg2/gpg@2.4.4-2ubuntu17 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + gnupg2/gpg-agent@2.4.4-2ubuntu17 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - ca-certificates@20240203 + apt@2.7.14build2 - openssl@3.0.13-0ubuntu3.3 + apt/libapt-pkg6.0t64@2.7.14build2 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • 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.12.6 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + apt@2.7.14build2 - libssh/libssh-4@0.10.6-2build2 + gnupg2/gpgv@2.4.4-2ubuntu17 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • 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 + docker-image|quay.io/argoproj/argocd@v2.12.6 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + gnupg2/gpg@2.4.4-2ubuntu17 - krb5/libkrb5-3@1.20.1-6ubuntu2.1 + gnupg2/gpgconf@2.4.4-2ubuntu17 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1
    • 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.12.6 - 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 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - openssl@3.0.13-0ubuntu3.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + pam/libpam-modules@1.5.3-5ubuntu5.1 - ca-certificates@20240203 + systemd/libsystemd0@255.4-1ubuntu8.4 - openssl@3.0.13-0ubuntu3.3 + libgcrypt20@1.10.3-2build1 @@ -658,28 +623,28 @@

      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 libgcrypt20 package and not the libgcrypt20 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 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 openssl.

      +

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      References


    -

    CVE-2024-6119

    +

    CVE-2024-26462

    @@ -690,7 +655,7 @@

    CVE-2024-6119

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -698,13 +663,13 @@

      CVE-2024-6119

    • Vulnerable module: - openssl/libssl3t64 + krb5/libk5crypto3
    • 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.12.6, git@1:2.43.0-1ubuntu7.1 and others
    @@ -716,135 +681,146 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - openssl/libssl3t64@3.0.13-0ubuntu3.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + git@1:2.43.0-1ubuntu7.1 - coreutils@9.4-3ubuntu6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + 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 + docker-image|quay.io/argoproj/argocd@v2.12.6 - libfido2/libfido2-1@1.14.0-1build3 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - openssh/openssh-client@1:9.6p1-3ubuntu13.5 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.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
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - ca-certificates@20240203 + git@1:2.43.0-1ubuntu7.1 - openssl@3.0.13-0ubuntu3.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.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 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - libssh/libssh-4@0.10.6-2build2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3t64@3.0.13-0ubuntu3.3 + krb5/libkrb5-3@1.20.1-6ubuntu2.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.12.6 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - krb5/libkrb5-3@1.20.1-6ubuntu2.1 - - openssl/libssl3t64@3.0.13-0ubuntu3.3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 - - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - - openssl/libssl3t64@3.0.13-0ubuntu3.3 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl@3.0.13-0ubuntu3.3 + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - ca-certificates@20240203 + docker-image|quay.io/argoproj/argocd@v2.12.6 - openssl@3.0.13-0ubuntu3.3 + krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -856,48 +832,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 krb5 package and not the krb5 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.

      +

      Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/kdc/ndr.c.

      Remediation

      -

      Upgrade Ubuntu:24.04 openssl to version 3.0.13-0ubuntu3.4 or higher.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References


    -

    Information Exposure

    +

    LGPL-3.0 license

    @@ -908,20 +863,20 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - libgcrypt20 + gopkg.in/retry.v1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and libgcrypt20@1.10.3-2build1 + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3
    @@ -934,100 +889,69 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + github.com/argoproj/argo-cd/v2@* - libgcrypt20@1.10.3-2build1 + gopkg.in/retry.v1@v1.0.3
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - gnupg2/dirmngr@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - gnupg2/gpg@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - gnupg2/gpg-agent@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 - - +
    + +

    LGPL-3.0 license

    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - apt@2.7.14build2 - - apt/libapt-pkg6.0t64@2.7.14build2 - - libgcrypt20@1.10.3-2build1 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - apt@2.7.14build2 - - gnupg2/gpgv@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - gnupg2/gpg@2.4.4-2ubuntu17 - - gnupg2/gpgconf@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 - - +
  • +
    +

    Denial of Service (DoS)

    +
    - +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.6/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: - docker-image|quay.io/argoproj/argocd@v2.12.3 - - apt@2.7.14build2 - - adduser@3.137ubuntu1 - - shadow/passwd@1:4.13+dfsg1-4ubuntu3 - - pam/libpam-modules@1.5.3-5ubuntu5.1 - - systemd/libsystemd0@255.4-1ubuntu8.4 + github.com/argoproj/argo-cd/v2@* - libgcrypt20@1.10.3-2build1 + github.com/rs/cors@v1.9.0 @@ -1038,29 +962,67 @@

      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: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.

      +

      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

      -

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      +

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

      References


    -

    CVE-2024-26462

    +

    MPL-2.0 license

    @@ -1071,21 +1033,21 @@

    CVE-2024-26462

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • - Package Manager: ubuntu:24.04 + Package Manager: golang
    • - Vulnerable module: + Module: - krb5/libk5crypto3 + github.com/r3labs/diff
    • Introduced through: + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1097,178 +1059,90 @@

    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 + github.com/r3labs/diff@v1.1.0
    • -
    • - 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 - - +
    + +

    MPL-2.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

    +
    - -
  • - 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 - - +
    + medium severity +
    -
  • -
  • - 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 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - - +
    -
  • +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.6/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 + github.com/argoproj/argo-cd/v2@* - krb5/krb5-locales@1.20.1-6ubuntu2.1 + github.com/hashicorp/go-version@v1.6.0
    • -
    - -
    - -
    - -

    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/kdc/ndr.c.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 krb5.

    -

    References

    - + + +
    + +
    + +

    MPL-2.0 license


    -

    Denial of Service (DoS)

    +

    MPL-2.0 license

    @@ -1279,20 +1153,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.12.6/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang
    • - Vulnerable module: + Module: - github.com/rs/cors + github.com/hashicorp/go-retryablehttp
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.7
    @@ -1307,7 +1181,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - github.com/rs/cors@v1.9.0 + github.com/hashicorp/go-retryablehttp@v0.7.7 @@ -1318,67 +1192,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 +1213,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/helm/v3 /usr/local/bin/helm
    • - Package Manager: ubuntu:24.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.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1415,11 +1239,9 @@

    Detailed paths

    -

    XML External Entity (XXE) Injection

    +

    MPL-2.0 license

    @@ -1462,21 +1273,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.12.6/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
    @@ -1488,11 +1299,9 @@

    Detailed paths

    -

    Integer Overflow or Wraparound

    +

    MPL-2.0 license

    @@ -1535,21 +1333,21 @@

    Integer Overflow or Wraparound

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/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.13.1 - docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1561,11 +1359,9 @@

    Detailed paths

    -
    -

    CVE-2024-8096

    +
    +

    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.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1616,13 +1401,13 @@

      CVE-2024-8096

    • Vulnerable module: - curl/libcurl3t64-gnutls + patch
    • Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 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 +1419,9 @@

    Detailed paths

    -

    Release of Invalid Pointer or Reference

    +

    Double Free

    @@ -1682,7 +1463,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.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1695,7 +1476,7 @@

      Release of Invalid Pointer or Reference

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 and patch@2.7.6-7build3 + docker-image|quay.io/argoproj/argocd@v2.12.6 and patch@2.7.6-7build3
    @@ -1708,7 +1489,7 @@

    Detailed paths

    -

    Double Free

    +

    CVE-2024-41996

    @@ -1752,7 +1538,7 @@

    Double Free

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1760,12 +1546,12 @@

      Double Free

    • 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.12.6 and openssl/libssl3t64@3.0.13-0ubuntu3.4
    @@ -1778,9 +1564,135 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 - patch@2.7.6-7build3 + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + 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.12.6 + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + 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.12.6 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + 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.12.6 + + openssl@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.6 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.4 @@ -1792,26 +1704,23 @@

      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. +

      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.

      -

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

      +

      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 patch.

      +

      There is no fixed version for Ubuntu:24.04 openssl.

      References


    @@ -1827,7 +1736,7 @@

    CVE-2024-26458

    • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:24.04 @@ -1841,7 +1750,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.12.6, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1853,11 +1762,11 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1868,11 +1777,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1885,11 +1794,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1900,11 +1809,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1917,11 +1826,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1936,11 +1845,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1951,7 +1860,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 openssh/openssh-client@1:9.6p1-3ubuntu13.5 @@ -1962,11 +1871,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1975,11 +1884,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 libssh/libssh-4@0.10.6-2build2 @@ -1990,7 +1899,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -2035,7 +1944,7 @@

      CVE-2024-26461

      • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:24.04 @@ -2049,7 +1958,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.12.6, git@1:2.43.0-1ubuntu7.1 and others
      @@ -2061,11 +1970,11 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2076,11 +1985,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2093,11 +2002,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2108,11 +2017,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2125,11 +2034,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2144,11 +2053,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2159,7 +2068,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 openssh/openssh-client@1:9.6p1-3ubuntu13.5 @@ -2170,11 +2079,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2183,11 +2092,11 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 libssh/libssh-4@0.10.6-2build2 @@ -2198,7 +2107,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -2243,7 +2152,7 @@

        Out-of-bounds Write

        • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2256,7 +2165,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.12.6 and gnupg2/gpgv@2.4.4-2ubuntu17
        @@ -2269,7 +2178,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/gpgv@2.4.4-2ubuntu17 @@ -2278,7 +2187,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 apt@2.7.14build2 @@ -2289,7 +2198,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -2300,7 +2209,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -2311,7 +2220,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/gpg@2.4.4-2ubuntu17 @@ -2322,7 +2231,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/dirmngr@2.4.4-2ubuntu17 @@ -2331,7 +2240,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/gpg@2.4.4-2ubuntu17 @@ -2340,7 +2249,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -2389,7 +2298,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.12.6/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:24.04 @@ -2402,7 +2311,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.12.6 and glibc/libc-bin@2.39-0ubuntu8.3
        @@ -2415,7 +2324,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 glibc/libc-bin@2.39-0ubuntu8.3 @@ -2424,7 +2333,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 glibc/libc6@2.39-0ubuntu8.3 @@ -2470,7 +2379,7 @@

          Improper Input Validation

          • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:24.04 @@ -2484,7 +2393,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.12.6, git@1:2.43.0-1ubuntu7.1 and others
          @@ -2496,7 +2405,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 @@ -2507,7 +2416,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git@1:2.43.0-1ubuntu7.1 @@ -2516,7 +2425,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 git-lfs@3.4.1-1ubuntu0.1 @@ -2563,7 +2472,7 @@

            Improper Input Validation

            • - Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.12.6/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:24.04 @@ -2576,7 +2485,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.12.6 and coreutils@9.4-3ubuntu6
            @@ -2589,7 +2498,7 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.12.3 + docker-image|quay.io/argoproj/argocd@v2.12.6 coreutils@9.4-3ubuntu6 diff --git a/docs/snyk/v2.12.3/redis_7.0.15-alpine.html b/docs/snyk/v2.12.6/redis_7.0.15-alpine.html similarity index 53% rename from docs/snyk/v2.12.3/redis_7.0.15-alpine.html rename to docs/snyk/v2.12.6/redis_7.0.15-alpine.html index 222dff64476b7..aad2c7d0a4f20 100644 --- a/docs/snyk/v2.12.3/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.12.6/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)

              +

              October 27th 2024, 12:24:56 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,189 @@

    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.13.0-rc5/argocd-iac-install.html b/docs/snyk/v2.13.0-rc5/argocd-iac-install.html new file mode 100644 index 0000000000000..36538b9879297 --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/argocd-iac-install.html @@ -0,0 +1,2891 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:23:51 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • /argo-cd/manifests/install.yaml (Kubernetes)
    • +
    +
    + +
    +
    44 total issues
    +
    +
    +
    +
    + +
    + + + + + + +
    Project manifests/install.yaml
    Path /argo-cd/manifests/install.yaml
    Project Type Kubernetes
    +
    +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 17] + + rules[5] + + resources + +
    • + +
    • + Line number: 22392 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[0] + + resources + +
    • + +
    • + Line number: 22073 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 11] + + rules[4] + + resources + +
    • + +
    • + Line number: 22160 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 12] + + rules[0] + + resources + +
    • + +
    • + Line number: 22188 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[1] + + resources + +
    • + +
    • + Line number: 22218 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[3] + + resources + +
    • + +
    • + Line number: 22236 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 14] + + rules[0] + + resources + +
    • + +
    • + Line number: 22254 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 15] + + rules[0] + + resources + +
    • + +
    • + Line number: 22276 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 48] + + spec + + template + + spec + + initContainers[secret-init] + + imagePullPolicy + +
    • + +
    • + Line number: 23349 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 49] + + spec + + template + + spec + + initContainers[copyutil] + + imagePullPolicy + +
    • + +
    • + Line number: 23648 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 22886 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23155 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23109 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23215 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23320 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23344 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23648 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23401 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23733 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 24123 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container is running with multiple open ports

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-36 +
    • + +
    • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + ports + +
    • + +
    • + Line number: 23135 +
    • +
    + +
    + +

    Impact

    +

    Increases the attack surface of the application and the container.

    + +

    Remediation

    +

    Reduce `ports` count to 2

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 45] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
    • + +
    • + Line number: 22886 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
    • + +
    • + Line number: 23109 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 48] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
    • + +
    • + Line number: 23320 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 22886 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23109 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23155 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23215 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23320 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23344 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23648 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23401 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23733 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 24123 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23033 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23163 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23138 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23254 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23337 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23351 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23655 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23621 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 24024 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 24324 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +
    + +
    + + + diff --git a/docs/snyk/v2.13.0-rc5/argocd-iac-namespace-install.html b/docs/snyk/v2.13.0-rc5/argocd-iac-namespace-install.html new file mode 100644 index 0000000000000..ea4c42c063507 --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/argocd-iac-namespace-install.html @@ -0,0 +1,2845 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:24:01 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • /argo-cd/manifests/namespace-install.yaml (Kubernetes)
    • +
    +
    + +
    +
    43 total issues
    +
    +
    +
    +
    + +
    + + + + + + +
    Project manifests/namespace-install.yaml
    Path /argo-cd/manifests/namespace-install.yaml
    Project Type Kubernetes
    +
    +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 7] + + rules[0] + + resources + +
    • + +
    • + Line number: 77 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 8] + + rules[4] + + resources + +
    • + +
    • + Line number: 164 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 9] + + rules[0] + + resources + +
    • + +
    • + Line number: 192 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[1] + + resources + +
    • + +
    • + Line number: 222 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[3] + + resources + +
    • + +
    • + Line number: 240 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 11] + + rules[0] + + resources + +
    • + +
    • + Line number: 258 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 12] + + rules[0] + + resources + +
    • + +
    • + Line number: 280 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 39] + + spec + + template + + spec + + initContainers[secret-init] + + imagePullPolicy + +
    • + +
    • + Line number: 1138 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 40] + + spec + + template + + spec + + initContainers[copyutil] + + imagePullPolicy + +
    • + +
    • + Line number: 1437 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 675 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 944 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 898 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1004 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1109 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1133 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1437 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1190 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1522 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1912 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container is running with multiple open ports

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-36 +
    • + +
    • Introduced through: + [DocId: 37] + + spec + + template + + spec + + containers[dex] + + ports + +
    • + +
    • + Line number: 924 +
    • +
    + +
    + +

    Impact

    +

    Increases the attack surface of the application and the container.

    + +

    Remediation

    +

    Reduce `ports` count to 2

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 36] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
    • + +
    • + Line number: 675 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 37] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
    • + +
    • + Line number: 898 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 39] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
    • + +
    • + Line number: 1109 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 675 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
    • + +
    • + Line number: 898 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 944 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1004 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1109 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1133 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1437 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1190 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1522 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1912 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 822 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 952 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 927 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1043 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1126 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + initContainers[secret-init] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1140 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1444 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1410 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1813 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 2113 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +
    + +
    + + + diff --git a/docs/snyk/v2.13.0-rc5/argocd-test.html b/docs/snyk/v2.13.0-rc5/argocd-test.html new file mode 100644 index 0000000000000..e51a7755420f0 --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/argocd-test.html @@ -0,0 +1,1208 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:21:47 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
    +
    25 vulnerable dependency paths
    +
    2132 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    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

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.0-rc5/ghcr.io_dexidp_dex_v2.41.1.html b/docs/snyk/v2.13.0-rc5/ghcr.io_dexidp_dex_v2.41.1.html new file mode 100644 index 0000000000000..ea2e0e88444e0 --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/ghcr.io_dexidp_dex_v2.41.1.html @@ -0,0 +1,2089 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:21:53 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)
    • +
    +
    + +
    +
    22 known vulnerabilities
    +
    43 vulnerable dependency paths
    +
    969 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    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.0-rc5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.13.0-rc5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html new file mode 100644 index 0000000000000..5f8ac81bef351 --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -0,0 +1,1497 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:21:57 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

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

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

    + +
    + + + +
    +
    +

    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.0-rc5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.13.0-rc5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..4c579b6bf07ff --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,666 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:22:00 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.13.0-rc5/quay.io_argoproj_argocd_v2.13.0-rc5.html b/docs/snyk/v2.13.0-rc5/quay.io_argoproj_argocd_v2.13.0-rc5.html new file mode 100644 index 0000000000000..f0116b92b1e2d --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/quay.io_argoproj_argocd_v2.13.0-rc5.html @@ -0,0 +1,2432 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:22:23 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc5//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc5/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc5/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    +
    + +
    +
    18 known vulnerabilities
    +
    72 vulnerable dependency paths
    +
    2355 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Information Exposure

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + apt@2.7.14build2 + + apt/libapt-pkg6.0t64@2.7.14build2 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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@v2.13.0-rc5 + + 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

    + + +
    + + + +
    +
    +

    CVE-2024-26462

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + krb5/krb5-locales@1.20.1-6ubuntu2.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/kdc/ndr.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/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

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/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: + github.com/argoproj/argo-cd/v2@* + + 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.0-rc5/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: + github.com/argoproj/argo-cd/v2@* + + 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.0-rc5/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:v2.13.0-rc5/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:v2.13.0-rc5/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:v2.13.0-rc5/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:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3t64 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and openssl/libssl3t64@3.0.13-0ubuntu3.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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.0-rc5 + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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.0-rc5 + + 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.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + 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.0-rc5 + + openssl@3.0.13-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + 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

    + + +
    + + + +
    +
    +

    CVE-2024-26458

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + krb5/krb5-locales@1.20.1-6ubuntu2.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 in /krb5/src/lib/rpc/pmap_rmt.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-26461

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + 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.13.0-rc5 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + krb5/krb5-locales@1.20.1-6ubuntu2.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.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + gnupg2/gpgv +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and gnupg2/gpgv@2.4.4-2ubuntu17 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + + +
    • +
    + +
    + +
    + +

    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: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:24.04 gnupg2.

    +

    References

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and glibc/libc-bin@2.39-0ubuntu8.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + glibc/libc-bin@2.39-0ubuntu8.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + glibc/libc6@2.39-0ubuntu8.3 + + + +
    • +
    + +
    + +
    + +

    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: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:24.04 glibc.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + git/git-man +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + git/git-man@1:2.43.0-1ubuntu7.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git@1:2.43.0-1ubuntu7.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + git-lfs@3.4.1-1ubuntu0.1 + + git@1:2.43.0-1ubuntu7.1 + + + +
    • +
    + +
    + +
    + +

    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:24.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).

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 git.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc5/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + coreutils +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 and coreutils@9.4-3ubuntu6 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc5 + + coreutils@9.4-3ubuntu6 + + + +
    • +
    + +
    + +
    + +

    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: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:24.04 coreutils.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.0-rc5/redis_7.0.15-alpine.html b/docs/snyk/v2.13.0-rc5/redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..9d7d0e81b21bc --- /dev/null +++ b/docs/snyk/v2.13.0-rc5/redis_7.0.15-alpine.html @@ -0,0 +1,666 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 27th 2024, 12:22:27 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • redis:7.0.15-alpine (apk)
    • +
    • 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|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/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/commands/argocd.md b/docs/user-guide/commands/argocd.md index 0514eb9447103..135e026177d01 100644 --- a/docs/user-guide/commands/argocd.md +++ b/docs/user-guide/commands/argocd.md @@ -18,6 +18,7 @@ argocd [flags] --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 + --force-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. --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) @@ -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..39ff3977520ec 100644 --- a/docs/user-guide/commands/argocd_account.md +++ b/docs/user-guide/commands/argocd_account.md @@ -59,6 +59,7 @@ argocd account [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_bcrypt.md b/docs/user-guide/commands/argocd_account_bcrypt.md index d4bde8b933424..3c1496df8e2fa 100644 --- a/docs/user-guide/commands/argocd_account_bcrypt.md +++ b/docs/user-guide/commands/argocd_account_bcrypt.md @@ -32,6 +32,7 @@ argocd account bcrypt --password YOUR_PASSWORD --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_can-i.md b/docs/user-guide/commands/argocd_account_can-i.md index f6fd5a01880a8..22f59e9270c10 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 certificates accounts gpgkeys logs exec extensions] ``` @@ -42,6 +42,7 @@ Resources: [clusters projects applications applicationsets repositories certific --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_delete-token.md b/docs/user-guide/commands/argocd_account_delete-token.md index 25d5b9a37d17a..1da988cabad8b 100644 --- a/docs/user-guide/commands/argocd_account_delete-token.md +++ b/docs/user-guide/commands/argocd_account_delete-token.md @@ -35,6 +35,7 @@ argocd account delete-token --account ID --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_generate-token.md b/docs/user-guide/commands/argocd_account_generate-token.md index e149548374894..ba559f77afecf 100644 --- a/docs/user-guide/commands/argocd_account_generate-token.md +++ b/docs/user-guide/commands/argocd_account_generate-token.md @@ -37,6 +37,7 @@ argocd account generate-token --account --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 + --force-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. --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) 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..6813254ce9099 100644 --- a/docs/user-guide/commands/argocd_account_get-user-info.md +++ b/docs/user-guide/commands/argocd_account_get-user-info.md @@ -35,6 +35,7 @@ argocd account get-user-info [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_get.md b/docs/user-guide/commands/argocd_account_get.md index 70d181e702a17..a09ffd3372e5f 100644 --- a/docs/user-guide/commands/argocd_account_get.md +++ b/docs/user-guide/commands/argocd_account_get.md @@ -36,6 +36,7 @@ argocd account get --account --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_list.md b/docs/user-guide/commands/argocd_account_list.md index 6af9d8a6d0ee0..a502d04d2d2d1 100644 --- a/docs/user-guide/commands/argocd_account_list.md +++ b/docs/user-guide/commands/argocd_account_list.md @@ -31,6 +31,7 @@ argocd account list --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_account_update-password.md b/docs/user-guide/commands/argocd_account_update-password.md index 3a31b6ee06274..8bb57f44fcb97 100644 --- a/docs/user-guide/commands/argocd_account_update-password.md +++ b/docs/user-guide/commands/argocd_account_update-password.md @@ -47,6 +47,7 @@ argocd account update-password [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md index ec1de309c135b..4e771fdbb3a31 100644 --- a/docs/user-guide/commands/argocd_admin.md +++ b/docs/user-guide/commands/argocd_admin.md @@ -37,6 +37,7 @@ $ argocd admin initial-password reset --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_app.md b/docs/user-guide/commands/argocd_admin_app.md index 12fa400c8c94d..458031a307871 100644 --- a/docs/user-guide/commands/argocd_admin_app.md +++ b/docs/user-guide/commands/argocd_admin_app.md @@ -39,6 +39,7 @@ argocd admin app get-reconcile-results APPNAME --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 + --force-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. --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) 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..1a79097d1c553 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 @@ -24,6 +24,7 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags] --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 + --force-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. --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) 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..abb54ae0ad3eb 100644 --- a/docs/user-guide/commands/argocd_admin_app_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_app_generate-spec.md @@ -56,6 +56,7 @@ 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-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for generate-spec --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values @@ -113,6 +114,7 @@ argocd admin app generate-spec APPNAME [flags] --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 + --force-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. --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) 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..cd89accbac1ef 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 @@ -50,6 +50,7 @@ argocd admin app get-reconcile-results PATH [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index 7abe6fd1a42f8..8cb1a25756727 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -38,6 +38,7 @@ argocd admin cluster namespaces my-cluster --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 + --force-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. --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) 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..4286c75cf1b5f 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 @@ -47,6 +48,7 @@ argocd admin cluster generate-spec CONTEXT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 37092a4ef303a..9482c610440ac 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -61,6 +61,7 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md index 791f61ec1c1f0..0b99b1d0a2f11 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md @@ -44,6 +44,7 @@ argocd admin cluster namespaces [flags] --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 + --force-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. --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) 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..4f362d8d7d1bd 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 @@ -45,6 +45,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags] --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 + --force-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. --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) 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..a413fb3aad496 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 @@ -47,6 +47,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index b624c8dbe6c49..137707f475c21 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -60,6 +60,7 @@ argocd admin cluster shards [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index b894959c1c0c3..734a8067bea8b 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -74,6 +74,7 @@ argocd admin cluster stats target-cluster --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index ecfee6be3a242..bc68dd8f89111 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -61,6 +61,7 @@ $ argocd admin dashboard --redis-compress gzip --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md index f4fe070f2d1f5..f40423629cb72 100644 --- a/docs/user-guide/commands/argocd_admin_export.md +++ b/docs/user-guide/commands/argocd_admin_export.md @@ -47,6 +47,7 @@ argocd admin export [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md index b373184a3796d..dc45bda43506f 100644 --- a/docs/user-guide/commands/argocd_admin_import.md +++ b/docs/user-guide/commands/argocd_admin_import.md @@ -23,6 +23,7 @@ argocd admin import SOURCE [flags] --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 --dry-run Print what will be performed + --force-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. -h, --help help for import --ignore-tracking Do not update the tracking annotation if the resource is already tracked --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md index 92feb9e8ad9f5..1ef4fc57366ee 100644 --- a/docs/user-guide/commands/argocd_admin_initial-password.md +++ b/docs/user-guide/commands/argocd_admin_initial-password.md @@ -44,6 +44,7 @@ argocd admin initial-password [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md index 58f2b832bebbb..a36b6b2f53423 100644 --- a/docs/user-guide/commands/argocd_admin_notifications.md +++ b/docs/user-guide/commands/argocd_admin_notifications.md @@ -49,6 +49,7 @@ argocd admin notifications [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_notifications_template.md b/docs/user-guide/commands/argocd_admin_notifications_template.md index 2a93df1a9a9f1..27c0140cda83e 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template.md @@ -37,6 +37,7 @@ argocd admin notifications template [flags] --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..6cddf153d8aa7 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md @@ -49,6 +49,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..311ac306dd269 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md @@ -50,6 +50,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger.md b/docs/user-guide/commands/argocd_admin_notifications_trigger.md index 74b8460151e2e..fd8519bbcb13e 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger.md @@ -37,6 +37,7 @@ argocd admin notifications trigger [flags] --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..23975a630a4ea 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md @@ -49,6 +49,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..1d1e939da2a13 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md @@ -49,6 +49,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_proj.md b/docs/user-guide/commands/argocd_admin_proj.md index e4f11de54cab1..8b40bd00db35e 100644 --- a/docs/user-guide/commands/argocd_admin_proj.md +++ b/docs/user-guide/commands/argocd_admin_proj.md @@ -24,6 +24,7 @@ argocd admin proj [flags] --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 + --force-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. --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) 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..14e0f6bae5d83 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 @@ -52,6 +52,7 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project --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 + --force-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. --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) 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..8abf22e18eec3 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-spec.md @@ -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 @@ -51,6 +52,7 @@ argocd admin proj generate-spec PROJECT [flags] --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 + --force-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. --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) 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..24720bce09977 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 @@ -60,6 +60,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] --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 + --force-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. --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) 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..061afe7297e34 100644 --- a/docs/user-guide/commands/argocd_admin_redis-initial-password.md +++ b/docs/user-guide/commands/argocd_admin_redis-initial-password.md @@ -44,6 +44,7 @@ argocd admin redis-initial-password [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_repo.md b/docs/user-guide/commands/argocd_admin_repo.md index 33944fda2d87c..83e65ab0a7a4c 100644 --- a/docs/user-guide/commands/argocd_admin_repo.md +++ b/docs/user-guide/commands/argocd_admin_repo.md @@ -24,6 +24,7 @@ argocd admin repo [flags] --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 + --force-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. --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) 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..463bff6571e25 100644 --- a/docs/user-guide/commands/argocd_admin_repo_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_repo_generate-spec.md @@ -72,6 +72,7 @@ argocd admin repo generate-spec REPOURL [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md index d2726048afc42..ad8ace4739a91 100644 --- a/docs/user-guide/commands/argocd_admin_settings.md +++ b/docs/user-guide/commands/argocd_admin_settings.md @@ -47,6 +47,7 @@ argocd admin settings [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac.md b/docs/user-guide/commands/argocd_admin_settings_rbac.md index 5cb18ba1a0580..5deeb9e7c39bc 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac.md @@ -35,6 +35,7 @@ argocd admin settings rbac [flags] --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..db809bc2ced1b 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md @@ -81,6 +81,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau --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 + --force-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. --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) 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..2803e124adcb6 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -73,6 +73,7 @@ argocd admin settings rbac validate --namespace argocd --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 + --force-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. --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) 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..4e370f33a9c9e 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md @@ -35,6 +35,7 @@ argocd admin settings resource-overrides [flags] --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..78f8fb6c6bad2 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 @@ -46,6 +46,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..af60558a2f5b1 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 @@ -46,6 +46,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..8a95ed2ce1577 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 @@ -47,6 +47,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml - --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..f4b212e87b135 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 @@ -46,6 +46,7 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) 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..560d68a95f473 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 @@ -46,6 +46,7 @@ argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --a --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_admin_settings_validate.md b/docs/user-guide/commands/argocd_admin_settings_validate.md index 1565397fb5117..fa03e4b9b0944 100644 --- a/docs/user-guide/commands/argocd_admin_settings_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_validate.md @@ -51,6 +51,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s --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 --disable-compression If true, opt-out of response compression for all requests to the server + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index ea5bf74d6a56a..7b675f3b08bca 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -56,6 +56,7 @@ argocd app [flags] --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 + --force-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. --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) @@ -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 diff --git a/docs/user-guide/commands/argocd_app_actions.md b/docs/user-guide/commands/argocd_app_actions.md index 21df6d1f1564e..701b7826055a9 100644 --- a/docs/user-guide/commands/argocd_app_actions.md +++ b/docs/user-guide/commands/argocd_app_actions.md @@ -34,6 +34,7 @@ argocd app actions [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_actions_list.md b/docs/user-guide/commands/argocd_app_actions_list.md index 513042b746278..ad4213d8dbae3 100644 --- a/docs/user-guide/commands/argocd_app_actions_list.md +++ b/docs/user-guide/commands/argocd_app_actions_list.md @@ -36,6 +36,7 @@ argocd app actions list APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_actions_run.md b/docs/user-guide/commands/argocd_app_actions_run.md index 8dc105243793b..6dc22f63a4029 100644 --- a/docs/user-guide/commands/argocd_app_actions_run.md +++ b/docs/user-guide/commands/argocd_app_actions_run.md @@ -36,6 +36,7 @@ argocd app actions run APPNAME ACTION [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_add-source.md b/docs/user-guide/commands/argocd_app_add-source.md index b6bc3ae3de6c2..98fdb57a6f37a 100644 --- a/docs/user-guide/commands/argocd_app_add-source.md +++ b/docs/user-guide/commands/argocd_app_add-source.md @@ -38,6 +38,7 @@ 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-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for add-source --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values @@ -90,6 +91,7 @@ argocd app add-source APPNAME [flags] --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 + --force-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. --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) 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..ae495beb4b3d0 --- /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 + --force-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. + --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 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..4ba51b98779df 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -58,6 +58,7 @@ 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-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for create --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values @@ -114,6 +115,7 @@ argocd app create APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_delete-resource.md b/docs/user-guide/commands/argocd_app_delete-resource.md index 892de087ec811..612b87ebc7f27 100644 --- a/docs/user-guide/commands/argocd_app_delete-resource.md +++ b/docs/user-guide/commands/argocd_app_delete-resource.md @@ -32,6 +32,7 @@ argocd app delete-resource APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_delete.md b/docs/user-guide/commands/argocd_app_delete.md index 15ccb486220ad..a5e8e19d2742f 100644 --- a/docs/user-guide/commands/argocd_app_delete.md +++ b/docs/user-guide/commands/argocd_app_delete.md @@ -47,6 +47,7 @@ argocd app delete APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_diff.md b/docs/user-guide/commands/argocd_app_diff.md index 07efe70af6b40..f86f76d20891e 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) @@ -43,6 +44,7 @@ argocd app diff APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index 684e77e12ce5a..145bf6a14c1e7 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -25,6 +25,7 @@ argocd app edit APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index 8785e5b52637b..8f132f0a2cb68 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -65,6 +65,7 @@ argocd app get APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_history.md b/docs/user-guide/commands/argocd_app_history.md index 81c2127ab8d6c..214a172dc3a27 100644 --- a/docs/user-guide/commands/argocd_app_history.md +++ b/docs/user-guide/commands/argocd_app_history.md @@ -26,6 +26,7 @@ argocd app history APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_list.md b/docs/user-guide/commands/argocd_app_list.md index 843716f549771..935db600e9eb5 100644 --- a/docs/user-guide/commands/argocd_app_list.md +++ b/docs/user-guide/commands/argocd_app_list.md @@ -44,6 +44,7 @@ argocd app list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_logs.md b/docs/user-guide/commands/argocd_app_logs.md index decb6b05fd808..fc6d62c559dd4 100644 --- a/docs/user-guide/commands/argocd_app_logs.md +++ b/docs/user-guide/commands/argocd_app_logs.md @@ -75,6 +75,7 @@ argocd app logs APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_manifests.md b/docs/user-guide/commands/argocd_app_manifests.md index 3238a7cfcf2d3..3a0a748f58613 100644 --- a/docs/user-guide/commands/argocd_app_manifests.md +++ b/docs/user-guide/commands/argocd_app_manifests.md @@ -43,6 +43,7 @@ argocd app manifests APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_patch-resource.md b/docs/user-guide/commands/argocd_app_patch-resource.md index 392c3c87e7014..d6a305207b5d8 100644 --- a/docs/user-guide/commands/argocd_app_patch-resource.md +++ b/docs/user-guide/commands/argocd_app_patch-resource.md @@ -32,6 +32,7 @@ argocd app patch-resource APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_patch.md b/docs/user-guide/commands/argocd_app_patch.md index 90375448ce3af..330121c919ee6 100644 --- a/docs/user-guide/commands/argocd_app_patch.md +++ b/docs/user-guide/commands/argocd_app_patch.md @@ -37,6 +37,7 @@ argocd app patch APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index d9741e108ce86..213e71f298f29 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -33,6 +33,7 @@ argocd app remove-source APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_resources.md b/docs/user-guide/commands/argocd_app_resources.md index 9e3b43c5e1bfa..938ddc0c1a76b 100644 --- a/docs/user-guide/commands/argocd_app_resources.md +++ b/docs/user-guide/commands/argocd_app_resources.md @@ -27,6 +27,7 @@ argocd app resources APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_rollback.md b/docs/user-guide/commands/argocd_app_rollback.md index 47adea4a19a3a..cb0eaab1462a8 100644 --- a/docs/user-guide/commands/argocd_app_rollback.md +++ b/docs/user-guide/commands/argocd_app_rollback.md @@ -28,6 +28,7 @@ argocd app rollback APPNAME [ID] [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 878d6e098e3ca..fde1b520984eb 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -47,6 +47,7 @@ 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-tests Skip helm test manifests installation step --helm-version string Helm version -h, --help help for set --ignore-missing-value-files Ignore locally missing valueFiles when setting helm template --values @@ -100,6 +101,7 @@ argocd app set APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index 00d37d33747ff..5bef5958bba39 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -82,6 +82,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_terminate-op.md b/docs/user-guide/commands/argocd_app_terminate-op.md index 37cf70b9ea058..4d35f3c269419 100644 --- a/docs/user-guide/commands/argocd_app_terminate-op.md +++ b/docs/user-guide/commands/argocd_app_terminate-op.md @@ -24,6 +24,7 @@ argocd app terminate-op APPNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 177f1b095dd69..0eebf2299f711 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -55,6 +55,7 @@ argocd app unset APPNAME parameters [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_app_wait.md b/docs/user-guide/commands/argocd_app_wait.md index 867484e3432b1..97a0bfbc799ed 100644 --- a/docs/user-guide/commands/argocd_app_wait.md +++ b/docs/user-guide/commands/argocd_app_wait.md @@ -62,6 +62,7 @@ argocd app wait [APPNAME.. | -l selector] [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset.md b/docs/user-guide/commands/argocd_appset.md index 39c25dcca8fa7..0b85b766201b7 100644 --- a/docs/user-guide/commands/argocd_appset.md +++ b/docs/user-guide/commands/argocd_appset.md @@ -59,6 +59,7 @@ argocd appset [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset_create.md b/docs/user-guide/commands/argocd_appset_create.md index ac0b1427dd7af..4272dcec6de6b 100644 --- a/docs/user-guide/commands/argocd_appset_create.md +++ b/docs/user-guide/commands/argocd_appset_create.md @@ -37,6 +37,7 @@ argocd appset create [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset_delete.md b/docs/user-guide/commands/argocd_appset_delete.md index 90510a42073c0..3e448d81b35fa 100644 --- a/docs/user-guide/commands/argocd_appset_delete.md +++ b/docs/user-guide/commands/argocd_appset_delete.md @@ -32,6 +32,7 @@ argocd appset delete [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset_generate.md b/docs/user-guide/commands/argocd_appset_generate.md index 8c7db6e8ac9c0..958a3c9b7cac7 100644 --- a/docs/user-guide/commands/argocd_appset_generate.md +++ b/docs/user-guide/commands/argocd_appset_generate.md @@ -32,6 +32,7 @@ argocd appset generate [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset_get.md b/docs/user-guide/commands/argocd_appset_get.md index 76b3e3946988b..ba2f9ee4e7571 100644 --- a/docs/user-guide/commands/argocd_appset_get.md +++ b/docs/user-guide/commands/argocd_appset_get.md @@ -33,6 +33,7 @@ argocd appset get APPSETNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_appset_list.md b/docs/user-guide/commands/argocd_appset_list.md index fad42ce7e240c..0d9897532b96c 100644 --- a/docs/user-guide/commands/argocd_appset_list.md +++ b/docs/user-guide/commands/argocd_appset_list.md @@ -35,6 +35,7 @@ argocd appset list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cert.md b/docs/user-guide/commands/argocd_cert.md index 1e0db72b0452b..452f2e32f5906 100644 --- a/docs/user-guide/commands/argocd_cert.md +++ b/docs/user-guide/commands/argocd_cert.md @@ -66,6 +66,7 @@ argocd cert [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cert_add-ssh.md b/docs/user-guide/commands/argocd_cert_add-ssh.md index a32d12e18ea32..bdaad1ed29a2d 100644 --- a/docs/user-guide/commands/argocd_cert_add-ssh.md +++ b/docs/user-guide/commands/argocd_cert_add-ssh.md @@ -27,6 +27,7 @@ argocd cert add-ssh --batch [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cert_add-tls.md b/docs/user-guide/commands/argocd_cert_add-tls.md index 0208a502836ac..d4c92a5d7d463 100644 --- a/docs/user-guide/commands/argocd_cert_add-tls.md +++ b/docs/user-guide/commands/argocd_cert_add-tls.md @@ -26,6 +26,7 @@ argocd cert add-tls SERVERNAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cert_list.md b/docs/user-guide/commands/argocd_cert_list.md index d3b80dfeac97f..5711e8fbb0596 100644 --- a/docs/user-guide/commands/argocd_cert_list.md +++ b/docs/user-guide/commands/argocd_cert_list.md @@ -28,6 +28,7 @@ argocd cert list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cert_rm.md b/docs/user-guide/commands/argocd_cert_rm.md index f76fb6a9a38c9..50d2346d9c8c7 100644 --- a/docs/user-guide/commands/argocd_cert_rm.md +++ b/docs/user-guide/commands/argocd_cert_rm.md @@ -26,6 +26,7 @@ argocd cert rm REPOSERVER [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster.md b/docs/user-guide/commands/argocd_cluster.md index 6f30e5a9308e4..513feaeb682e1 100644 --- a/docs/user-guide/commands/argocd_cluster.md +++ b/docs/user-guide/commands/argocd_cluster.md @@ -63,6 +63,7 @@ argocd cluster [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_add.md b/docs/user-guide/commands/argocd_cluster_add.md index cf1d9ba2d588e..9374553b27ba7 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") @@ -46,6 +48,7 @@ argocd cluster add CONTEXT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_get.md b/docs/user-guide/commands/argocd_cluster_get.md index 8b3fd5e410a04..4cd1b9873f8c9 100644 --- a/docs/user-guide/commands/argocd_cluster_get.md +++ b/docs/user-guide/commands/argocd_cluster_get.md @@ -32,6 +32,7 @@ argocd cluster get in-cluster --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_list.md b/docs/user-guide/commands/argocd_cluster_list.md index d7ffbeb7baa9f..5be82659b3d5a 100644 --- a/docs/user-guide/commands/argocd_cluster_list.md +++ b/docs/user-guide/commands/argocd_cluster_list.md @@ -47,6 +47,7 @@ argocd cluster list -o server --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_rm.md b/docs/user-guide/commands/argocd_cluster_rm.md index 667e5f9143cd4..3a1f17891a40f 100644 --- a/docs/user-guide/commands/argocd_cluster_rm.md +++ b/docs/user-guide/commands/argocd_cluster_rm.md @@ -32,6 +32,7 @@ argocd cluster rm cluster-name --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_rotate-auth.md b/docs/user-guide/commands/argocd_cluster_rotate-auth.md index f91c10f3ea6e2..788fe726e804f 100644 --- a/docs/user-guide/commands/argocd_cluster_rotate-auth.md +++ b/docs/user-guide/commands/argocd_cluster_rotate-auth.md @@ -31,6 +31,7 @@ argocd cluster rotate-auth cluster-name --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_cluster_set.md b/docs/user-guide/commands/argocd_cluster_set.md index 3d26a6ec29702..64074be2c0dc1 100644 --- a/docs/user-guide/commands/argocd_cluster_set.md +++ b/docs/user-guide/commands/argocd_cluster_set.md @@ -36,6 +36,7 @@ argocd cluster set NAME [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_completion.md b/docs/user-guide/commands/argocd_completion.md index 32c91ccbc2707..2c4bef4fdb8c2 100644 --- a/docs/user-guide/commands/argocd_completion.md +++ b/docs/user-guide/commands/argocd_completion.md @@ -59,6 +59,7 @@ $ source ~/.config/fish/completions/argocd.fish --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_configure.md b/docs/user-guide/commands/argocd_configure.md new file mode 100644 index 0000000000000..072e04e89e6dd --- /dev/null +++ b/docs/user-guide/commands/argocd_configure.md @@ -0,0 +1,81 @@ +# `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 + --force-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. + --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..3dceb9db5edf2 100644 --- a/docs/user-guide/commands/argocd_context.md +++ b/docs/user-guide/commands/argocd_context.md @@ -38,6 +38,7 @@ argocd context cd.argoproj.io --delete --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_gpg.md b/docs/user-guide/commands/argocd_gpg.md index 41941b1f2739c..b8b26013a3be5 100644 --- a/docs/user-guide/commands/argocd_gpg.md +++ b/docs/user-guide/commands/argocd_gpg.md @@ -43,6 +43,7 @@ argocd gpg [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index e0fd7ac55116f..7eed92f170278 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -32,6 +32,7 @@ argocd gpg add [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_gpg_get.md b/docs/user-guide/commands/argocd_gpg_get.md index 5e738b60d8906..edf135cc24583 100644 --- a/docs/user-guide/commands/argocd_gpg_get.md +++ b/docs/user-guide/commands/argocd_gpg_get.md @@ -38,6 +38,7 @@ argocd gpg get KEYID [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_gpg_list.md b/docs/user-guide/commands/argocd_gpg_list.md index 2d193caf677a6..1d0d6a8795aef 100644 --- a/docs/user-guide/commands/argocd_gpg_list.md +++ b/docs/user-guide/commands/argocd_gpg_list.md @@ -38,6 +38,7 @@ argocd gpg list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_gpg_rm.md b/docs/user-guide/commands/argocd_gpg_rm.md index 125f193bb473c..6fe33b8d4a15e 100644 --- a/docs/user-guide/commands/argocd_gpg_rm.md +++ b/docs/user-guide/commands/argocd_gpg_rm.md @@ -24,6 +24,7 @@ argocd gpg rm KEYID [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_login.md b/docs/user-guide/commands/argocd_login.md index c20247b01b283..9364c34ed83a5 100644 --- a/docs/user-guide/commands/argocd_login.md +++ b/docs/user-guide/commands/argocd_login.md @@ -48,6 +48,7 @@ argocd login cd.argoproj.io --core --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_logout.md b/docs/user-guide/commands/argocd_logout.md index 132e73fa5033f..71ba3935aba14 100644 --- a/docs/user-guide/commands/argocd_logout.md +++ b/docs/user-guide/commands/argocd_logout.md @@ -37,6 +37,7 @@ $ argocd logout --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj.md b/docs/user-guide/commands/argocd_proj.md index 8f35188d33634..7d8b8e9ffaedd 100644 --- a/docs/user-guide/commands/argocd_proj.md +++ b/docs/user-guide/commands/argocd_proj.md @@ -59,6 +59,7 @@ argocd proj [flags] --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 + --force-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. --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) 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..08951c4b2d442 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 @@ -35,6 +35,7 @@ argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACC --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_add-destination.md b/docs/user-guide/commands/argocd_proj_add-destination.md index d13f1a5234f7b..0d723f883db91 100644 --- a/docs/user-guide/commands/argocd_proj_add-destination.md +++ b/docs/user-guide/commands/argocd_proj_add-destination.md @@ -35,6 +35,7 @@ argocd proj add-destination PROJECT SERVER/NAME NAMESPACE [flags] --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 + --force-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. --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) 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..2739fbff0281f 100644 --- a/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md @@ -35,6 +35,7 @@ argocd proj add-orphaned-ignore PROJECT GROUP KIND [flags] --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 + --force-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. --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) 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..db3424da50609 100644 --- a/docs/user-guide/commands/argocd_proj_add-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_add-signature-key.md @@ -31,6 +31,7 @@ argocd proj add-signature-key PROJECT KEY-ID [flags] --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 + --force-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. --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) 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..7be9cd7463540 100644 --- a/docs/user-guide/commands/argocd_proj_add-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_add-source-namespace.md @@ -31,6 +31,7 @@ argocd proj add-source-namespace PROJECT NAMESPACE [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_add-source.md b/docs/user-guide/commands/argocd_proj_add-source.md index 0e64e29d0a3f4..45465fd298166 100644 --- a/docs/user-guide/commands/argocd_proj_add-source.md +++ b/docs/user-guide/commands/argocd_proj_add-source.md @@ -31,6 +31,7 @@ argocd proj add-source PROJECT URL [flags] --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 + --force-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. --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) 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..0c534715856e7 100644 --- a/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md @@ -32,6 +32,7 @@ argocd proj allow-cluster-resource PROJECT GROUP KIND [flags] --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 + --force-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. --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) 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..5908fcaff5757 100644 --- a/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md @@ -32,6 +32,7 @@ argocd proj allow-namespace-resource PROJECT GROUP KIND [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_create.md b/docs/user-guide/commands/argocd_proj_create.md index c8b27e35bb762..8366f1f35be92 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 @@ -47,6 +48,7 @@ argocd proj create PROJECT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_delete.md b/docs/user-guide/commands/argocd_proj_delete.md index b955732eb6067..99aae650dfbe4 100644 --- a/docs/user-guide/commands/argocd_proj_delete.md +++ b/docs/user-guide/commands/argocd_proj_delete.md @@ -31,6 +31,7 @@ argocd proj delete PROJECT [flags] --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 + --force-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. --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) 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..af9493c422f4b 100644 --- a/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md @@ -32,6 +32,7 @@ argocd proj deny-cluster-resource PROJECT GROUP KIND [flags] --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 + --force-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. --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) 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..d817764ba54b6 100644 --- a/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md @@ -32,6 +32,7 @@ argocd proj deny-namespace-resource PROJECT GROUP KIND [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_edit.md b/docs/user-guide/commands/argocd_proj_edit.md index 1955aa11ba2c4..f0cb77102ef94 100644 --- a/docs/user-guide/commands/argocd_proj_edit.md +++ b/docs/user-guide/commands/argocd_proj_edit.md @@ -31,6 +31,7 @@ argocd proj edit PROJECT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_get.md b/docs/user-guide/commands/argocd_proj_get.md index 930972018db05..17215d6f5e011 100644 --- a/docs/user-guide/commands/argocd_proj_get.md +++ b/docs/user-guide/commands/argocd_proj_get.md @@ -35,6 +35,7 @@ argocd proj get PROJECT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_list.md b/docs/user-guide/commands/argocd_proj_list.md index 2a71f43d68c3a..740bf342d512b 100644 --- a/docs/user-guide/commands/argocd_proj_list.md +++ b/docs/user-guide/commands/argocd_proj_list.md @@ -35,6 +35,7 @@ argocd proj list [flags] --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 + --force-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. --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) 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..5114eee3163ba 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 @@ -31,6 +31,7 @@ argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_remove-destination.md b/docs/user-guide/commands/argocd_proj_remove-destination.md index 88a702b2ed2b5..2e8375ebd8fbf 100644 --- a/docs/user-guide/commands/argocd_proj_remove-destination.md +++ b/docs/user-guide/commands/argocd_proj_remove-destination.md @@ -31,6 +31,7 @@ argocd proj remove-destination PROJECT SERVER NAMESPACE [flags] --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 + --force-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. --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) 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..0f868d5307f13 100644 --- a/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md @@ -35,6 +35,7 @@ argocd proj remove-orphaned-ignore PROJECT GROUP KIND [flags] --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 + --force-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. --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) 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..e13d60471ba1a 100644 --- a/docs/user-guide/commands/argocd_proj_remove-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_remove-signature-key.md @@ -31,6 +31,7 @@ argocd proj remove-signature-key PROJECT KEY-ID [flags] --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 + --force-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. --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) 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..5208e1c74c2ef 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_remove-source-namespace.md @@ -31,6 +31,7 @@ argocd proj remove-source-namespace PROJECT NAMESPACE [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_remove-source.md b/docs/user-guide/commands/argocd_proj_remove-source.md index 66c016fadd7e5..896d26f1d9c02 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source.md +++ b/docs/user-guide/commands/argocd_proj_remove-source.md @@ -31,6 +31,7 @@ argocd proj remove-source PROJECT URL [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_role.md b/docs/user-guide/commands/argocd_proj_role.md index 89d7abe87de4d..239049b4efeb8 100644 --- a/docs/user-guide/commands/argocd_proj_role.md +++ b/docs/user-guide/commands/argocd_proj_role.md @@ -24,6 +24,7 @@ argocd proj role [flags] --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 + --force-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. --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) 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..f796802f84f6c 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-group.md +++ b/docs/user-guide/commands/argocd_proj_role_add-group.md @@ -24,6 +24,7 @@ argocd proj role add-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --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 + --force-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. --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) 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..8a4eea96877af 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_add-policy.md @@ -56,6 +56,7 @@ ID ISSUED-AT EXPIRES-AT --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 + --force-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. --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) 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..8e8290e95655b 100644 --- a/docs/user-guide/commands/argocd_proj_role_create-token.md +++ b/docs/user-guide/commands/argocd_proj_role_create-token.md @@ -39,6 +39,7 @@ Create token succeeded for proj:test-project:test-role. --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_role_create.md b/docs/user-guide/commands/argocd_proj_role_create.md index 885c79f1672b3..19212eb494ae2 100644 --- a/docs/user-guide/commands/argocd_proj_role_create.md +++ b/docs/user-guide/commands/argocd_proj_role_create.md @@ -32,6 +32,7 @@ argocd proj role create PROJECT ROLE-NAME [flags] --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 + --force-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. --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) 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..04c888b0bc8b8 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete-token.md +++ b/docs/user-guide/commands/argocd_proj_role_delete-token.md @@ -56,6 +56,7 @@ $ argocd proj role delete-token test-project test-role 1696769937 --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index 97e01627e371a..4d6c427007523 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -30,6 +30,7 @@ $ argocd proj role delete test-project test-role --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_role_get.md b/docs/user-guide/commands/argocd_proj_role_get.md index d35b8768b47b2..e87bf83a67010 100644 --- a/docs/user-guide/commands/argocd_proj_role_get.md +++ b/docs/user-guide/commands/argocd_proj_role_get.md @@ -39,6 +39,7 @@ ID ISSUED-AT EXPIRES-AT --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 + --force-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. --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) 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..d7628ea3ccbec 100644 --- a/docs/user-guide/commands/argocd_proj_role_list-tokens.md +++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md @@ -35,6 +35,7 @@ fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index 34b62a3cf4beb..f490378262f6e 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -35,6 +35,7 @@ argocd proj role list PROJECT [flags] --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 + --force-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. --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) 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..8159b8cb19131 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-group.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-group.md @@ -24,6 +24,7 @@ argocd proj role remove-group PROJECT ROLE-NAME GROUP-CLAIM [flags] --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 + --force-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. --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) 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..9796c03b02384 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-policy.md @@ -56,6 +56,7 @@ ID ISSUED-AT EXPIRES-AT --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_set.md b/docs/user-guide/commands/argocd_proj_set.md index 7b4d79ff13588..a9cce63859346 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 @@ -45,6 +46,7 @@ argocd proj set PROJECT [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index b02a6772a8582..904d7b80e34d4 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -41,6 +41,7 @@ argocd proj windows list --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index beb158b9c6243..d833537bf08b1 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -55,6 +55,7 @@ argocd proj windows add PROJECT \ --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 2fc4ef2c43390..751530bec182d 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -35,6 +35,7 @@ argocd proj windows delete new-project 1 --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 + --force-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. --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) 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..5b9309c77d956 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 @@ -39,6 +39,7 @@ argocd proj windows disable-manual-sync default 0 --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 + --force-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. --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) 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..32bcb877233c9 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 @@ -42,6 +42,7 @@ argocd proj windows enable-manual-sync my-app-project --message "Manual sync ini --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index 5f15f34dfe948..63e238f0e85f9 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -39,6 +39,7 @@ argocd proj windows list test-project --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_proj_windows_update.md b/docs/user-guide/commands/argocd_proj_windows_update.md index a3405c0650be8..523fd1faa5e61 100644 --- a/docs/user-guide/commands/argocd_proj_windows_update.md +++ b/docs/user-guide/commands/argocd_proj_windows_update.md @@ -43,6 +43,7 @@ argocd proj windows update PROJECT ID \ --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_relogin.md b/docs/user-guide/commands/argocd_relogin.md index 8891d35b896dd..b191ce270ec92 100644 --- a/docs/user-guide/commands/argocd_relogin.md +++ b/docs/user-guide/commands/argocd_relogin.md @@ -48,6 +48,7 @@ argocd login cd.argoproj.io --core --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repo.md b/docs/user-guide/commands/argocd_repo.md index 3e6548df9a5a7..b9e189c9cbe5c 100644 --- a/docs/user-guide/commands/argocd_repo.md +++ b/docs/user-guide/commands/argocd_repo.md @@ -61,6 +61,7 @@ argocd repo rm https://github.com/yourusername/your-repo.git --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repo_add.md b/docs/user-guide/commands/argocd_repo_add.md index 4abb437cf7bdc..8d6c6f94660da 100644 --- a/docs/user-guide/commands/argocd_repo_add.md +++ b/docs/user-guide/commands/argocd_repo_add.md @@ -86,6 +86,7 @@ argocd repo add REPOURL [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repo_get.md b/docs/user-guide/commands/argocd_repo_get.md index b28d30e1e0037..be33efa2edbe8 100644 --- a/docs/user-guide/commands/argocd_repo_get.md +++ b/docs/user-guide/commands/argocd_repo_get.md @@ -27,6 +27,7 @@ argocd repo get [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repo_list.md b/docs/user-guide/commands/argocd_repo_list.md index 5a13cff85c5fc..9911d27333bd2 100644 --- a/docs/user-guide/commands/argocd_repo_list.md +++ b/docs/user-guide/commands/argocd_repo_list.md @@ -26,6 +26,7 @@ argocd repo list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repo_rm.md b/docs/user-guide/commands/argocd_repo_rm.md index 4b784e0a6d1c1..db32621314470 100644 --- a/docs/user-guide/commands/argocd_repo_rm.md +++ b/docs/user-guide/commands/argocd_repo_rm.md @@ -25,6 +25,7 @@ argocd repo rm REPO [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repocreds.md b/docs/user-guide/commands/argocd_repocreds.md index cac91d9700bf5..6fc3a7d886721 100644 --- a/docs/user-guide/commands/argocd_repocreds.md +++ b/docs/user-guide/commands/argocd_repocreds.md @@ -56,6 +56,7 @@ argocd repocreds [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repocreds_add.md b/docs/user-guide/commands/argocd_repocreds_add.md index 39405519def40..49c0b763bf01e 100644 --- a/docs/user-guide/commands/argocd_repocreds_add.md +++ b/docs/user-guide/commands/argocd_repocreds_add.md @@ -62,6 +62,7 @@ argocd repocreds add REPOURL [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repocreds_list.md b/docs/user-guide/commands/argocd_repocreds_list.md index ebcf308bdc766..570afe42d0c6a 100644 --- a/docs/user-guide/commands/argocd_repocreds_list.md +++ b/docs/user-guide/commands/argocd_repocreds_list.md @@ -41,6 +41,7 @@ argocd repocreds list [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_repocreds_rm.md b/docs/user-guide/commands/argocd_repocreds_rm.md index 6893bd3dc3db9..8603f37b70b8e 100644 --- a/docs/user-guide/commands/argocd_repocreds_rm.md +++ b/docs/user-guide/commands/argocd_repocreds_rm.md @@ -31,6 +31,7 @@ argocd repocreds rm CREDSURL [flags] --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 + --force-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. --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) diff --git a/docs/user-guide/commands/argocd_version.md b/docs/user-guide/commands/argocd_version.md index bd6505cc1c622..2d0b5ce788654 100644 --- a/docs/user-guide/commands/argocd_version.md +++ b/docs/user-guide/commands/argocd_version.md @@ -63,6 +63,7 @@ argocd version [flags] --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 + --force-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. --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) 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..cae8ffdcefca2 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,23 @@ spec: helm: skipCrds: 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/kustomize.md b/docs/user-guide/kustomize.md index e9c01e98a7488..100622cf03ea8 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -19,6 +19,7 @@ spec: namespace: default server: 'https://kubernetes.default.svc' ``` + If the `kustomization.yaml` file exists at the location pointed to by `repoURL` and `path`, Argo CD will render the manifests using Kustomize. The following configuration options are available for Kustomize: 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/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/go.mod b/go.mod index d3b6084f32571..3e4774bed563e 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,17 @@ go 1.22.0 require ( code.gitea.io/sdk/gitea v0.19.0 - github.com/Azure/kubelogin v0.0.20 + github.com/Azure/kubelogin v0.1.4 github.com/Masterminds/semver/v3 v3.3.0 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.20241107145828-847cfc9f8b20 + 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 @@ -22,7 +22,7 @@ require ( 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.4 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 @@ -39,7 +39,7 @@ 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 @@ -59,16 +59,16 @@ require ( github.com/itchyny/gojq v0.12.16 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 @@ -77,22 +77,22 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/valyala/fasttemplate v1.2.2 - github.com/xanzy/go-gitlab v0.109.0 + github.com/xanzy/go-gitlab v0.113.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 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 + go.opentelemetry.io/otel v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 + go.opentelemetry.io/otel/sdk v1.31.0 + golang.org/x/crypto v0.29.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 + golang.org/x/net v0.30.0 + golang.org/x/oauth2 v0.24.0 + golang.org/x/sync v0.9.0 + golang.org/x/term v0.26.0 + golang.org/x/time v0.8.0 + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 + google.golang.org/grpc v1.67.1 + google.golang.org/protobuf v1.35.1 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/controller-runtime v0.19.1 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 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.12.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.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,7 +137,7 @@ 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 @@ -145,26 +145,25 @@ require ( github.com/googleapis/gax-go/v2 v2.12.0 // 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.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/sys v0.27.0 // indirect + golang.org/x/text v0.20.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 + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // 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 +208,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 @@ -271,11 +270,11 @@ require ( 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.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.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 @@ -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..8191561cebff5 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,19 @@ 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.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= 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 +32,10 @@ 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.4 h1:QxIqna3+o7l8K7JmPX69jdlHDEakAC0+A45hxu+OwNE= +github.com/Azure/kubelogin v0.1.4/go.mod h1:aWUXhjtwLzS/k/xJCTSAL4pgdjnkam1yM+2i59sLy8I= +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= @@ -83,10 +84,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.20241107145828-847cfc9f8b20 h1:BmqPFHuhV6vyS6Bv+yLIlJRt3quwqfJlmXGtfpLmYZs= +github.com/argoproj/gitops-engine v0.7.1-0.20241107145828-847cfc9f8b20/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM= +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,8 +142,9 @@ 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= @@ -204,8 +206,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.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8= +github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM= 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 +224,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= @@ -307,7 +307,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 +386,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= @@ -607,8 +606,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 +682,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 +792,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 +811,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 +840,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 +854,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= @@ -949,8 +947,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.113.0 h1:v5O4R+YZbJGxKqa9iIZxjMyeKkMKBN8P6sZsNl+YckM= +github.com/xanzy/go-gitlab v0.113.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= @@ -971,20 +969,20 @@ 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/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/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= 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 +991,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,8 +1040,8 @@ 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.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= 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= @@ -1125,16 +1125,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.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= 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 +1150,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.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.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 +1189,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 +1221,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.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.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,8 +1247,8 @@ 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.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= 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= @@ -1269,13 +1268,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.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= 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= @@ -1345,10 +1344,10 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY 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/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/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 +1363,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.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 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 +1372,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.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/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 +1384,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 +1414,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 +1430,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 +1454,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.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk= +sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= 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= diff --git a/hack/gen-catalog/main.go b/hack/gen-catalog/main.go index ff3da21d6791d..c7963dbf83ab4 100644 --- a/hack/gen-catalog/main.go +++ b/hack/gen-catalog/main.go @@ -168,7 +168,7 @@ func generateCommandsDocs(out io.Writer) error { for _, c := range toolSubCommand.Commands() { var cmdDesc bytes.Buffer if err := doc.GenMarkdown(c, &cmdDesc); err != nil { - return err + return fmt.Errorf("error generating Markdown for command: %v : %w", c, err) } for _, line := range strings.Split(cmdDesc.String(), "\n") { if strings.HasPrefix(line, "### SEE ALSO") { @@ -194,19 +194,19 @@ func buildConfigFromFS(templatesDir string, triggersDir string) (map[string]serv templatesCfg := map[string]services.Notification{} err := filepath.Walk(templatesDir, func(p string, info os.FileInfo, e error) error { if e != nil { - return e + return fmt.Errorf("error navigating the templates dirctory: %s : %w", templatesDir, e) } if info.IsDir() { return nil } data, err := os.ReadFile(p) if err != nil { - return err + return fmt.Errorf("error reading the template file: %s : %w", p, err) } name := strings.Split(path.Base(p), ".")[0] var template services.Notification if err := yaml.Unmarshal(data, &template); err != nil { - return err + return fmt.Errorf("error unmarshaling the data from file: %s : %w", p, err) } templatesCfg[name] = template return nil @@ -218,19 +218,19 @@ func buildConfigFromFS(templatesDir string, triggersDir string) (map[string]serv triggersCfg := map[string][]triggers.Condition{} err = filepath.Walk(triggersDir, func(p string, info os.FileInfo, e error) error { if e != nil { - return e + return fmt.Errorf("error navigating the triggers dirctory: %s : %w", triggersDir, e) } if info.IsDir() { return nil } data, err := os.ReadFile(p) if err != nil { - return err + return fmt.Errorf("error reading the trigger file: %s : %w", p, err) } name := strings.Split(path.Base(p), ".")[0] var trigger []triggers.Condition if err := yaml.Unmarshal(data, &trigger); err != nil { - return err + return fmt.Errorf("error unmarshaling the data from file: %s : %w", p, err) } triggersCfg[name] = trigger return nil diff --git a/hack/gen-docs/main.go b/hack/gen-docs/main.go index c641e833417d3..c39f4628a432c 100644 --- a/hack/gen-docs/main.go +++ b/hack/gen-docs/main.go @@ -37,7 +37,7 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin sort.Strings(files) data, err := os.ReadFile("mkdocs.yml") if err != nil { - return err + return fmt.Errorf("error reading mkdocs.yml: %w", err) } var un unstructured.Unstructured if e := yaml.Unmarshal(data, &un.Object); e != nil { @@ -46,12 +46,12 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin nav := un.Object["nav"].([]interface{}) rootitem, _ := findNavItem(nav, parent) if rootitem == nil { - return fmt.Errorf("Can't find '%s' root item in mkdoc.yml", parent) + return fmt.Errorf("can't find '%s' root item in mkdoc.yml", parent) } rootnavitemmap := rootitem.(map[interface{}]interface{}) childnav, _ := findNavItem(rootnavitemmap[parent].([]interface{}), child) if childnav == nil { - return fmt.Errorf("Can't find '%s' chile item under '%s' parent item in mkdoc.yml", child, parent) + return fmt.Errorf("can't find '%s' chile item under '%s' parent item in mkdoc.yml", child, parent) } childnavmap := childnav.(map[interface{}]interface{}) @@ -63,7 +63,7 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin childnavmap[child] = append(childnavitems, commands) newmkdocs, err := yaml.Marshal(un.Object) if err != nil { - return err + return fmt.Errorf("error in marshaling final configmap: %w", err) } // The marshaller drops custom tags, so re-add this one. Turns out this is much less invasive than trying to handle diff --git a/hack/gen-resources/util/gen_options_parser.go b/hack/gen-resources/util/gen_options_parser.go index 8446dd5c07754..22c36ab661a58 100644 --- a/hack/gen-resources/util/gen_options_parser.go +++ b/hack/gen-resources/util/gen_options_parser.go @@ -1,6 +1,7 @@ package util import ( + "fmt" "os" "gopkg.in/yaml.v2" @@ -55,7 +56,7 @@ func setDefaults(opts *GenerateOpts) { func Parse(opts *GenerateOpts, file string) error { fp, err := os.ReadFile(file) if err != nil { - return err + return fmt.Errorf("error reading the template file: %s : %w", file, err) } if e := yaml.Unmarshal(fp, &opts); e != nil { 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..1176649313121 --- /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, test.expected, "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-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/install-lint-tools.sh b/hack/installers/install-lint-tools.sh index 54e7b725478c8..0692263df3a2b 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.61.0 + +GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}" diff --git a/hack/known_types/main.go b/hack/known_types/main.go index e6647396c3c39..247fadffd908c 100644 --- a/hack/known_types/main.go +++ b/hack/known_types/main.go @@ -42,7 +42,7 @@ func newCommand() *cobra.Command { imprt := importer.ForCompiler(token.NewFileSet(), "source", nil) pkg, err := imprt.Import(packagePath) if err != nil { - return err + return fmt.Errorf("error while importing the package at: %s : %w", packagePath, err) } shortPackagePath := strings.TrimPrefix(packagePath, packagePrefix) @@ -78,7 +78,7 @@ func init() {%s }`, strings.Join(mapItems, "")) if docsOutputPath != "" { if err = os.WriteFile(docsOutputPath, []byte(strings.Join(docs, "\n")), 0o644); err != nil { - return err + return fmt.Errorf("error while writing to the %s: %w", docsOutputPath, err) } } diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 28ca1cda431da..407a6dd14b88b 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.15.4 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-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/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 619c4ca4817b8..3398ece8ef8d3 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,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -264,3 +282,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..9e07525a27982 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -100,6 +100,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -208,6 +226,8 @@ spec: name: argocd-cmd-params-cm key: controller.ignore.normalizer.jq.timeout optional: true + - name: KUBECACHEDIR + value: /tmp/kubecache image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -236,6 +256,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 +277,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 +296,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/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..328dfcb2146f6 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -385,3 +385,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-rbac/server/argocd-server-clusterrole.yaml b/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml index b33820950fcb6..3ee074622c15c 100644 --- a/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml +++ b/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml @@ -15,6 +15,7 @@ rules: - delete # supports deletion a live object in UI - get # supports viewing live object manifest in UI - patch # supports `argocd app patch` + - list # supports `argocd appset generate` with cluster generator - apiGroups: - "" resources: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index f558902d4692d..c5714d95fc1eb 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,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -670,6 +679,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1151,6 +1164,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1508,6 +1525,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2030,6 +2051,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2399,6 +2424,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2710,6 +2739,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 +2947,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3300,6 +3338,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3804,6 +3846,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4185,6 +4231,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4460,6 +4510,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4710,6 +4762,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5091,6 +5147,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5579,6 +5639,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5809,6 +5871,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6013,6 +6077,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6267,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6431,6 +6499,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6824,6 +6894,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7054,6 +7126,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7427,6 +7501,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7657,6 +7733,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8055,6 +8133,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8285,6 +8365,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8489,6 +8571,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +8761,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8907,6 +8993,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9300,6 +9388,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9530,6 +9620,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9903,6 +9995,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10133,6 +10227,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10514,6 +10610,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10744,6 +10842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11344,6 +11444,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11574,6 +11676,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12169,6 +12273,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12399,6 +12505,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12789,6 +12897,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13019,6 +13129,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13419,6 +13531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13649,6 +13763,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13853,6 +13969,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +14159,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14271,6 +14391,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14664,6 +14786,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14894,6 +15018,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15267,6 +15393,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15497,6 +15625,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15878,6 +16008,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16108,6 +16240,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16708,6 +16842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16938,6 +17074,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17533,6 +17671,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17763,6 +17903,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18157,6 +18299,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18387,6 +18531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18767,6 +18913,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18997,6 +19145,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19597,6 +19747,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19827,6 +19979,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20422,6 +20576,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20652,6 +20808,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21117,6 +21275,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21347,6 +21507,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21617,6 +21779,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +21899,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 +21910,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 +22665,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 +22731,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 +22767,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 +22869,8 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 999 @@ -22857,6 +23040,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 +23184,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -23145,6 +23336,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -23253,6 +23462,8 @@ spec: key: controller.ignore.normalizer.jq.timeout 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 +23491,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..1f08621786eeb 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,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -669,6 +678,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1150,6 +1163,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1507,6 +1524,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2029,6 +2050,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2398,6 +2423,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2709,6 +2738,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 +2946,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3299,6 +3337,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3803,6 +3845,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4184,6 +4230,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4459,6 +4509,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4709,6 +4761,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5090,6 +5146,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index ddfa9b27be056..b9a8c84e0620d 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -231,6 +231,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -461,6 +463,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -665,6 +669,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -853,6 +859,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1083,6 +1091,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1476,6 +1486,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -1706,6 +1718,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2079,6 +2093,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2309,6 +2325,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2707,6 +2725,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -2937,6 +2957,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3141,6 +3163,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -3329,6 +3353,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3559,6 +3585,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -3952,6 +3980,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4182,6 +4212,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4555,6 +4587,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -4785,6 +4819,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5166,6 +5202,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5396,6 +5434,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5996,6 +6036,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6226,6 +6268,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6821,6 +6865,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7051,6 +7097,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7441,6 +7489,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7671,6 +7721,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8071,6 +8123,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8301,6 +8355,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8505,6 +8561,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8693,6 +8751,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8923,6 +8983,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9316,6 +9378,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9546,6 +9610,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9919,6 +9985,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10149,6 +10217,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10530,6 +10600,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10760,6 +10832,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11360,6 +11434,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11590,6 +11666,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12185,6 +12263,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12415,6 +12495,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12809,6 +12891,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13039,6 +13123,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13419,6 +13505,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13649,6 +13737,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14249,6 +14339,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14479,6 +14571,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15074,6 +15168,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15304,6 +15400,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15769,6 +15867,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15999,6 +16099,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16269,6 +16371,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/install.yaml b/manifests/ha/install.yaml index ba37a63431b6b..aa71c208ed4cc 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,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -670,6 +679,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1151,6 +1164,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1508,6 +1525,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2030,6 +2051,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2399,6 +2424,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2710,6 +2739,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 +2947,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3300,6 +3338,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3804,6 +3846,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4185,6 +4231,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4460,6 +4510,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4710,6 +4762,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5091,6 +5147,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5579,6 +5639,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5809,6 +5871,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6013,6 +6077,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6267,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6431,6 +6499,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6824,6 +6894,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7054,6 +7126,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7427,6 +7501,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7657,6 +7733,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8055,6 +8133,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8285,6 +8365,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8489,6 +8571,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +8761,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8907,6 +8993,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9300,6 +9388,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9530,6 +9620,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9903,6 +9995,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10133,6 +10227,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10514,6 +10610,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10744,6 +10842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11344,6 +11444,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11574,6 +11676,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12169,6 +12273,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12399,6 +12505,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12789,6 +12897,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13019,6 +13129,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13419,6 +13531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13649,6 +13763,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13853,6 +13969,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +14159,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14271,6 +14391,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14664,6 +14786,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14894,6 +15018,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15267,6 +15393,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15497,6 +15625,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15878,6 +16008,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16108,6 +16240,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16708,6 +16842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16938,6 +17074,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17533,6 +17671,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17763,6 +17903,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18157,6 +18299,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18387,6 +18531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18767,6 +18913,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18997,6 +19145,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19597,6 +19747,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19827,6 +19979,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20422,6 +20576,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20652,6 +20808,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21117,6 +21275,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21347,6 +21507,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21617,6 +21779,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +21899,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 +21910,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: @@ -22463,6 +22630,7 @@ rules: - delete - get - patch + - list - apiGroups: - "" resources: @@ -23841,6 +24009,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 +24075,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 +24111,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 +24235,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -24142,6 +24326,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 +24638,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 +24782,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -24973,6 +25167,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 +25326,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -25238,6 +25452,8 @@ spec: key: controller.ignore.normalizer.jq.timeout 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 +25481,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 +25614,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.yaml b/manifests/ha/namespace-install.yaml index deefe124a2048..6f4231e7d4944 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: @@ -2766,6 +2792,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 +2951,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -3031,6 +3077,8 @@ spec: key: controller.ignore.normalizer.jq.timeout 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 +3106,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 +3239,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.yaml b/manifests/install.yaml index 6fd35145cb0ca..70db9f4a37e9f 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,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -670,6 +679,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1151,6 +1164,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -1508,6 +1525,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2030,6 +2051,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2399,6 +2424,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -2710,6 +2739,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 +2947,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3300,6 +3338,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -3804,6 +3846,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4185,6 +4231,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -4460,6 +4510,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -4710,6 +4762,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5091,6 +5147,10 @@ spec: description: SkipCrds skips custom resource definition installation step (Helm's --skip-crds) 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 @@ -5579,6 +5639,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -5809,6 +5871,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6013,6 +6077,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -6201,6 +6267,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6431,6 +6499,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -6824,6 +6894,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7054,6 +7126,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7427,6 +7501,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -7657,6 +7733,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8055,6 +8133,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8285,6 +8365,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8489,6 +8571,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -8677,6 +8761,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -8907,6 +8993,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9300,6 +9388,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9530,6 +9620,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -9903,6 +9995,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10133,6 +10227,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10514,6 +10610,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -10744,6 +10842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11344,6 +11444,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -11574,6 +11676,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12169,6 +12273,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12399,6 +12505,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -12789,6 +12897,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13019,6 +13129,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13419,6 +13531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13649,6 +13763,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -13853,6 +13969,8 @@ spec: type: object clusters: properties: + flatList: + type: boolean selector: properties: matchExpressions: @@ -14041,6 +14159,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14271,6 +14391,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14664,6 +14786,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -14894,6 +15018,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15267,6 +15393,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15497,6 +15625,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -15878,6 +16008,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16108,6 +16240,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16708,6 +16842,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -16938,6 +17074,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17533,6 +17671,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -17763,6 +17903,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18157,6 +18299,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18387,6 +18531,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18767,6 +18913,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -18997,6 +19145,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19597,6 +19747,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -19827,6 +19979,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20422,6 +20576,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -20652,6 +20808,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21117,6 +21275,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21347,6 +21507,8 @@ spec: type: string skipCrds: type: boolean + skipTests: + type: boolean valueFiles: items: type: string @@ -21617,6 +21779,8 @@ spec: type: string namespace: type: string + requiresDeletionConfirmation: + type: boolean requiresPruning: type: boolean status: @@ -21735,7 +21899,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 +21910,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: @@ -22430,6 +22597,7 @@ rules: - delete - get - patch + - list - apiGroups: - "" resources: @@ -22958,6 +23126,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 +23192,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 +23228,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 +23352,8 @@ spec: name: static-files - mountPath: /tmp name: dexconfig + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-dex-server volumes: - emptyDir: {} @@ -23259,6 +23443,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 +23539,8 @@ spec: runAsNonRoot: true seccompProfile: type: RuntimeDefault + nodeSelector: + kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 999 @@ -23522,6 +23710,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 +23854,8 @@ spec: volumeMounts: - mountPath: /var/run/argocd name: var-files + nodeSelector: + kubernetes.io/os: linux serviceAccountName: argocd-repo-server volumes: - configMap: @@ -24041,6 +24237,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 +24396,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -24306,6 +24522,8 @@ spec: key: controller.ignore.normalizer.jq.timeout 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 +24551,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.yaml b/manifests/namespace-install.yaml index 0d9c0816cfe30..73fe685010ae4 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: @@ -1834,6 +1862,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 +2021,24 @@ 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_REPO_SERVER_PLAINTEXT valueFrom: configMapKeyRef: @@ -2099,6 +2147,8 @@ spec: key: controller.ignore.normalizer.jq.timeout 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 +2176,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/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go index 3345756bd0aad..202228f7ef6f1 100644 --- a/pkg/apiclient/settings/settings.pb.go +++ b/pkg/apiclient/settings/settings.pb.go @@ -102,6 +102,7 @@ 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"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -315,6 +316,13 @@ func (m *Settings) GetImpersonationEnabled() bool { return false } +func (m *Settings) GetInstallationID() string { + if m != nil { + return m.InstallationID + } + return "" +} + 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 +756,86 @@ 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, + // 1249 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0x1b, 0xb7, + 0x12, 0xc7, 0x46, 0x8e, 0x2d, 0x8d, 0xe3, 0xc8, 0x66, 0x1c, 0x67, 0x23, 0xe4, 0xd9, 0x7a, 0x3a, + 0x04, 0x7a, 0x0f, 0xed, 0x2a, 0x56, 0x50, 0xb4, 0x08, 0x1a, 0xb4, 0x91, 0x14, 0x24, 0x6a, 0x9c, + 0xc4, 0xdd, 0xc4, 0x39, 0xf4, 0x12, 0xd0, 0xab, 0xe9, 0x6a, 0xeb, 0x15, 0xb9, 0x20, 0xb9, 0x6a, + 0x94, 0x63, 0x3f, 0x40, 0x0f, 0x6d, 0x3f, 0x4d, 0xef, 0x45, 0x7b, 0x2c, 0xd0, 0xbb, 0x51, 0x08, + 0xfd, 0x20, 0x05, 0xb9, 0x7f, 0xbc, 0x5e, 0xc9, 0x69, 0x81, 0xdc, 0xc8, 0xdf, 0x6f, 0xfe, 0x71, + 0x38, 0x43, 0x0e, 0xec, 0x4a, 0x14, 0x53, 0x14, 0x1d, 0x89, 0x4a, 0x05, 0xcc, 0x97, 0xf9, 0xc2, + 0x89, 0x04, 0x57, 0x9c, 0xac, 0x79, 0x61, 0x2c, 0x15, 0x8a, 0xc6, 0xb6, 0xcf, 0x7d, 0x6e, 0xb0, + 0x8e, 0x5e, 0x25, 0x74, 0xe3, 0x96, 0xcf, 0xb9, 0x1f, 0x62, 0x87, 0x46, 0x41, 0x87, 0x32, 0xc6, + 0x15, 0x55, 0x01, 0x67, 0xa9, 0x72, 0xe3, 0xc0, 0x0f, 0xd4, 0x38, 0x3e, 0x76, 0x3c, 0x3e, 0xe9, + 0x50, 0x61, 0xd4, 0xbf, 0x31, 0x8b, 0x0f, 0xbd, 0x51, 0x67, 0xda, 0xed, 0x44, 0x27, 0xbe, 0xd6, + 0x94, 0x1d, 0x1a, 0x45, 0x61, 0xe0, 0x19, 0xdd, 0xce, 0x74, 0x9f, 0x86, 0xd1, 0x98, 0xee, 0x77, + 0x7c, 0x64, 0x28, 0xa8, 0xc2, 0x51, 0x6a, 0xed, 0xf3, 0x7f, 0xb0, 0x56, 0x3e, 0x09, 0x0f, 0x46, + 0x5e, 0xc7, 0x0b, 0x69, 0x30, 0x49, 0xe3, 0x69, 0xd5, 0x61, 0xe3, 0x45, 0xca, 0x7e, 0x19, 0xa3, + 0x98, 0xb5, 0x7e, 0xb8, 0x02, 0xd5, 0x0c, 0x21, 0x37, 0xa1, 0x12, 0x8b, 0xd0, 0xb6, 0x9a, 0x56, + 0xbb, 0xd6, 0x5b, 0x9b, 0x9f, 0xee, 0x55, 0x8e, 0xdc, 0x03, 0x57, 0x63, 0xe4, 0x0e, 0xd4, 0x46, + 0xf8, 0xa6, 0xcf, 0xd9, 0xd7, 0x81, 0x6f, 0x5f, 0x6a, 0x5a, 0xed, 0xf5, 0x2e, 0x71, 0xd2, 0xcc, + 0x38, 0x83, 0x8c, 0x71, 0xcf, 0x84, 0x48, 0x1f, 0x40, 0xfb, 0x4f, 0x55, 0x2a, 0x46, 0xe5, 0x5a, + 0xae, 0xf2, 0x7c, 0x38, 0xe8, 0x27, 0x54, 0xef, 0xea, 0xfc, 0x74, 0x0f, 0xce, 0xf6, 0x6e, 0x41, + 0x8d, 0x34, 0x61, 0x9d, 0x46, 0xd1, 0x01, 0x3d, 0xc6, 0xf0, 0x09, 0xce, 0xec, 0x15, 0x1d, 0x99, + 0x5b, 0x84, 0xc8, 0x2b, 0xd8, 0x12, 0x28, 0x79, 0x2c, 0x3c, 0x7c, 0x3e, 0x45, 0x21, 0x82, 0x11, + 0x4a, 0xfb, 0x72, 0xb3, 0xd2, 0x5e, 0xef, 0xb6, 0x73, 0x6f, 0xd9, 0x09, 0x1d, 0xb7, 0x2c, 0xfa, + 0x90, 0x29, 0x31, 0x73, 0x17, 0x4d, 0x10, 0x07, 0x88, 0x54, 0x54, 0xc5, 0xb2, 0x47, 0x47, 0x3e, + 0x3e, 0x64, 0xf4, 0x38, 0xc4, 0x91, 0xbd, 0xda, 0xb4, 0xda, 0x55, 0x77, 0x09, 0x43, 0x1e, 0x43, + 0x3d, 0xa9, 0x84, 0x07, 0x8c, 0x86, 0x33, 0x15, 0x78, 0xd2, 0x5e, 0x33, 0x67, 0xde, 0xcd, 0xa3, + 0x78, 0x74, 0x9e, 0x4f, 0x8f, 0x5b, 0x56, 0x23, 0x6f, 0x61, 0xf3, 0x24, 0x96, 0x8a, 0x4f, 0x82, + 0xb7, 0xf8, 0x3c, 0x32, 0xd5, 0x64, 0x57, 0x8d, 0xa9, 0x67, 0xce, 0x59, 0x01, 0x38, 0x59, 0x01, + 0x98, 0xc5, 0x6b, 0x6f, 0xe4, 0x4c, 0xbb, 0x4e, 0x74, 0xe2, 0x3b, 0xba, 0x9c, 0x9c, 0x42, 0x39, + 0x39, 0x59, 0x39, 0x39, 0x4f, 0x4a, 0x56, 0xdd, 0x05, 0x3f, 0xe4, 0xbf, 0xb0, 0x32, 0xc6, 0x30, + 0xb2, 0x6b, 0xc6, 0xdf, 0x46, 0x1e, 0xfa, 0x63, 0x0c, 0x23, 0xd7, 0x50, 0xe4, 0x7f, 0xb0, 0x16, + 0x85, 0xb1, 0x1f, 0x30, 0x69, 0x83, 0x49, 0x73, 0x3d, 0x97, 0x3a, 0x34, 0xb8, 0x9b, 0xf1, 0x3a, + 0x87, 0xb1, 0x44, 0x71, 0xc0, 0xf5, 0x6e, 0x10, 0xc8, 0x24, 0x87, 0xeb, 0x49, 0x0e, 0x17, 0x19, + 0xf2, 0xbd, 0x05, 0x37, 0x3c, 0x93, 0x95, 0xa7, 0x94, 0x51, 0x1f, 0x27, 0xc8, 0xd4, 0x61, 0xea, + 0xeb, 0x8a, 0xf1, 0xf5, 0xf2, 0xfd, 0x32, 0xd0, 0x5f, 0x6a, 0xdc, 0xbd, 0xc8, 0x29, 0xf9, 0x00, + 0xb6, 0xf2, 0x14, 0xbd, 0x42, 0x21, 0xcd, 0x5d, 0x6c, 0x34, 0x2b, 0xed, 0x9a, 0xbb, 0x48, 0x90, + 0x06, 0x54, 0xe3, 0xa0, 0x2f, 0xe5, 0x91, 0x7b, 0x60, 0x5f, 0x35, 0x95, 0x9a, 0xef, 0x49, 0x1b, + 0xea, 0x71, 0xd0, 0xa3, 0x8c, 0xa1, 0xe8, 0x73, 0xa6, 0x90, 0x29, 0xbb, 0x6e, 0x44, 0xca, 0xb0, + 0x2e, 0xf9, 0x0c, 0xd2, 0x86, 0x36, 0x93, 0x92, 0x2f, 0x40, 0xda, 0x56, 0x44, 0xa5, 0xfc, 0x96, + 0x8b, 0xd1, 0x21, 0x55, 0x0a, 0x05, 0xb3, 0xb7, 0x12, 0x5b, 0x25, 0x98, 0xdc, 0x86, 0xab, 0x4a, + 0x50, 0xef, 0x24, 0x60, 0xfe, 0x53, 0x54, 0x63, 0x3e, 0xb2, 0x89, 0x11, 0x2c, 0xa1, 0xfa, 0x9c, + 0x99, 0x83, 0x43, 0x14, 0x13, 0xca, 0x74, 0x7c, 0xd7, 0xcc, 0x3d, 0x2d, 0x12, 0xe4, 0xff, 0xb0, + 0x99, 0x83, 0x5c, 0x06, 0x3a, 0xc5, 0xf6, 0xb6, 0xb1, 0xbb, 0x80, 0x97, 0xda, 0xc8, 0xe5, 0x5c, + 0x1d, 0x89, 0xd0, 0xbe, 0x6e, 0xa4, 0x97, 0x30, 0xfa, 0xf4, 0xf8, 0x06, 0xbd, 0xac, 0xdf, 0x76, + 0x4c, 0x0c, 0x45, 0x88, 0xdc, 0x81, 0x6b, 0x1e, 0x67, 0x4a, 0xf0, 0x30, 0x44, 0xf1, 0x8c, 0x4e, + 0x50, 0x46, 0xd4, 0x43, 0xfb, 0x86, 0x31, 0xb9, 0x8c, 0x22, 0x9f, 0xc2, 0x4d, 0x1a, 0x45, 0x72, + 0xc8, 0x1e, 0xb0, 0x59, 0x8e, 0x66, 0x1e, 0x6c, 0xe3, 0xe1, 0x62, 0x01, 0xd2, 0x85, 0xed, 0x60, + 0x12, 0xa1, 0x90, 0x9c, 0x99, 0x6a, 0xca, 0x14, 0x6f, 0x1a, 0xc5, 0xa5, 0x9c, 0xce, 0x7b, 0xc0, + 0xa4, 0xa2, 0x61, 0x68, 0xe0, 0xe1, 0xc0, 0x6e, 0x24, 0x79, 0x3f, 0x8f, 0x36, 0x7e, 0xb2, 0x60, + 0x67, 0xf9, 0x93, 0x44, 0x36, 0xa1, 0x72, 0x82, 0xb3, 0xe4, 0x2d, 0x76, 0xf5, 0x92, 0x8c, 0xe0, + 0xf2, 0x94, 0x86, 0x31, 0xa6, 0xcf, 0xef, 0x7b, 0x3e, 0x06, 0x65, 0xb7, 0x6e, 0x62, 0xfc, 0xde, + 0xa5, 0x4f, 0xac, 0xd6, 0x6b, 0xb8, 0xbe, 0xf4, 0xad, 0x22, 0xbb, 0x00, 0x59, 0xe5, 0x0c, 0x07, + 0x69, 0x6c, 0x05, 0x44, 0x9f, 0x9b, 0x32, 0xce, 0x66, 0xba, 0x2d, 0x8e, 0x24, 0x0a, 0x69, 0x62, + 0xad, 0xba, 0x25, 0xb4, 0x35, 0x80, 0x1b, 0xd9, 0x93, 0x9c, 0xb6, 0x9a, 0x8b, 0x32, 0xe2, 0x4c, + 0x62, 0xf1, 0x79, 0xb1, 0xde, 0xfd, 0xbc, 0xb4, 0x7e, 0xb6, 0x60, 0x45, 0x3f, 0x4c, 0xc4, 0x86, + 0x35, 0x6f, 0x4c, 0x4d, 0x65, 0x25, 0x31, 0x65, 0x5b, 0xdd, 0x92, 0x7a, 0xf9, 0x12, 0xdf, 0x28, + 0x13, 0x4a, 0xcd, 0xcd, 0xf7, 0xe4, 0x3e, 0xc0, 0x71, 0xc0, 0xa8, 0x98, 0x1d, 0x89, 0x50, 0xda, + 0x15, 0xe3, 0xec, 0x3f, 0xe7, 0x5e, 0x3c, 0xa7, 0x97, 0xf3, 0xc9, 0x3f, 0x51, 0x50, 0x68, 0xdc, + 0x87, 0x7a, 0x89, 0x5e, 0x72, 0x67, 0xdb, 0xc5, 0x3b, 0xab, 0x15, 0x73, 0x7c, 0x0b, 0x56, 0x93, + 0xf3, 0x10, 0x02, 0x2b, 0x8c, 0x4e, 0x30, 0x55, 0x33, 0xeb, 0xd6, 0x67, 0x50, 0xcb, 0x3f, 0x55, + 0xd2, 0x05, 0xf0, 0x38, 0x63, 0xe8, 0x29, 0x2e, 0xb2, 0xac, 0x9c, 0x7d, 0xbe, 0xfd, 0x8c, 0x72, + 0x0b, 0x52, 0xad, 0xbb, 0x50, 0xcb, 0x89, 0x65, 0x1e, 0x34, 0xa6, 0x66, 0x51, 0x16, 0x98, 0x59, + 0xb7, 0x7e, 0xa9, 0x40, 0xe1, 0x23, 0x5e, 0xaa, 0xb6, 0x03, 0xab, 0x81, 0x94, 0x31, 0x8a, 0x54, + 0x31, 0xdd, 0x91, 0x36, 0x54, 0xbd, 0x30, 0x40, 0xa6, 0x86, 0x03, 0xf3, 0xd7, 0xd7, 0x7a, 0x57, + 0xe6, 0xa7, 0x7b, 0xd5, 0x7e, 0x8a, 0xb9, 0x39, 0x4b, 0xf6, 0x61, 0xdd, 0x0b, 0x83, 0x8c, 0x48, + 0xbe, 0xf4, 0x5e, 0x7d, 0x7e, 0xba, 0xb7, 0xde, 0x3f, 0x18, 0xe6, 0xf2, 0x45, 0x19, 0xed, 0x54, + 0x7a, 0x3c, 0x4a, 0x3f, 0xf6, 0x9a, 0x9b, 0xee, 0xc8, 0x6b, 0xd8, 0x08, 0x46, 0x2f, 0xf9, 0x09, + 0xb2, 0xbe, 0x19, 0x72, 0xec, 0x55, 0x93, 0x9b, 0xdb, 0x4b, 0xa6, 0x0c, 0x67, 0x58, 0x14, 0x34, + 0xd7, 0xd5, 0xdb, 0x9a, 0x9f, 0xee, 0x6d, 0x0c, 0x07, 0x05, 0xdc, 0x3d, 0x6f, 0x8f, 0xdc, 0x03, + 0x1b, 0x4d, 0x4b, 0x1f, 0x3e, 0xe9, 0x3f, 0x7c, 0x10, 0xab, 0x31, 0x32, 0x95, 0x76, 0x92, 0xf9, + 0xdd, 0xab, 0xee, 0x85, 0x7c, 0x63, 0x06, 0x64, 0xd1, 0xe7, 0x92, 0x12, 0x79, 0x7a, 0xbe, 0xad, + 0x3f, 0x7e, 0x67, 0x5b, 0x27, 0x13, 0x9e, 0x93, 0x8f, 0xa8, 0x7a, 0x54, 0x72, 0x8c, 0xfd, 0x42, + 0x6d, 0x75, 0x7f, 0xb5, 0xa0, 0x9e, 0xf5, 0xd7, 0x0b, 0x14, 0xd3, 0xc0, 0x43, 0xf2, 0x05, 0x54, + 0x1e, 0xa1, 0x22, 0x3b, 0x0b, 0x33, 0x91, 0x99, 0x03, 0x1b, 0x5b, 0x0b, 0x78, 0xcb, 0xfe, 0xee, + 0x8f, 0xbf, 0x7e, 0xbc, 0x44, 0xc8, 0xa6, 0x99, 0x6d, 0xa7, 0xfb, 0xf9, 0x5c, 0x49, 0xc6, 0x00, + 0x8f, 0x30, 0xff, 0x24, 0x2f, 0x32, 0xd9, 0x5c, 0xc0, 0x4b, 0xbd, 0xde, 0x6a, 0x1a, 0x0f, 0x0d, + 0x62, 0x97, 0x3d, 0x74, 0xd2, 0x16, 0xef, 0xf5, 0x7f, 0x9b, 0xef, 0x5a, 0xbf, 0xcf, 0x77, 0xad, + 0x3f, 0xe7, 0xbb, 0xd6, 0x57, 0x1f, 0xfd, 0xbb, 0x69, 0x3a, 0x29, 0xb5, 0xdc, 0xd8, 0xf1, 0xaa, + 0x99, 0x7d, 0xef, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x99, 0x28, 0x60, 0x2e, 0xea, 0x0b, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -999,6 +1009,15 @@ func (m *Settings) 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 = encodeVarintSettings(dAtA, i, uint64(len(m.InstallationID))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } if m.ImpersonationEnabled { i-- if m.ImpersonationEnabled { @@ -1774,6 +1793,10 @@ 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 m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2884,6 +2907,38 @@ 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 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/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..3f31bf6dacd21 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4593,717 +4593,726 @@ 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, + // 11491 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6f, 0x70, 0x1c, 0xc9, + 0x75, 0x18, 0xae, 0xd9, 0xc5, 0x02, 0xbb, 0x0f, 0xff, 0x88, 0x26, 0x79, 0x87, 0xa3, 0x78, 0x07, + 0x7a, 0x4e, 0x3e, 0x9d, 0x7f, 0xba, 0x03, 0x7c, 0xf4, 0x9d, 0x7c, 0x3f, 0x9d, 0x25, 0x19, 0x7f, + 0x48, 0x10, 0x24, 0x40, 0xe0, 0x1a, 0x20, 0x29, 0x9d, 0x7c, 0x3a, 0x0d, 0x66, 0x1b, 0x8b, 0x21, + 0x66, 0x67, 0xf6, 0x66, 0x66, 0x41, 0xe0, 0x2c, 0xc9, 0x92, 0x25, 0xd9, 0x72, 0xf4, 0xe7, 0x14, + 0x29, 0x55, 0x39, 0x27, 0x96, 0x22, 0x5b, 0x4e, 0x2a, 0xa9, 0x94, 0x2a, 0x4a, 0xf2, 0x21, 0x4e, + 0xd9, 0x2e, 0x57, 0xec, 0x94, 0x4b, 0x89, 0x93, 0xb2, 0xa3, 0x52, 0x59, 0x4a, 0x62, 0x23, 0x12, + 0xe3, 0x94, 0x5d, 0xf9, 0xe0, 0xaa, 0x38, 0xf9, 0x90, 0x62, 0xfc, 0x21, 0xd5, 0xff, 0x7b, 0x66, + 0x67, 0x81, 0x05, 0x31, 0x20, 0x29, 0xe5, 0xbe, 0xed, 0xf6, 0x7b, 0xf3, 0x5e, 0x4f, 0x4f, 0xf7, + 0x7b, 0xaf, 0x5f, 0xbf, 0xf7, 0x1a, 0x16, 0x1b, 0x5e, 0xb2, 0xd9, 0x5e, 0x9f, 0x74, 0xc3, 0xe6, + 0x94, 0x13, 0x35, 0xc2, 0x56, 0x14, 0xde, 0x64, 0x3f, 0x9e, 0x76, 0xeb, 0x53, 0xdb, 0xe7, 0xa7, + 0x5a, 0x5b, 0x8d, 0x29, 0xa7, 0xe5, 0xc5, 0x53, 0x4e, 0xab, 0xe5, 0x7b, 0xae, 0x93, 0x78, 0x61, + 0x30, 0xb5, 0xfd, 0x8c, 0xe3, 0xb7, 0x36, 0x9d, 0x67, 0xa6, 0x1a, 0x24, 0x20, 0x91, 0x93, 0x90, + 0xfa, 0x64, 0x2b, 0x0a, 0x93, 0x10, 0xfd, 0x94, 0xa6, 0x36, 0x29, 0xa9, 0xb1, 0x1f, 0xaf, 0xb8, + 0xf5, 0xc9, 0xed, 0xf3, 0x93, 0xad, 0xad, 0xc6, 0x24, 0xa5, 0x36, 0x69, 0x50, 0x9b, 0x94, 0xd4, + 0xce, 0x3c, 0x6d, 0xf4, 0xa5, 0x11, 0x36, 0xc2, 0x29, 0x46, 0x74, 0xbd, 0xbd, 0xc1, 0xfe, 0xb1, + 0x3f, 0xec, 0x17, 0x67, 0x76, 0xc6, 0xde, 0x7a, 0x3e, 0x9e, 0xf4, 0x42, 0xda, 0xbd, 0x29, 0x37, + 0x8c, 0xc8, 0xd4, 0x76, 0x47, 0x87, 0xce, 0x5c, 0xd2, 0x38, 0x64, 0x27, 0x21, 0x41, 0xec, 0x85, + 0x41, 0xfc, 0x34, 0xed, 0x02, 0x89, 0xb6, 0x49, 0x64, 0xbe, 0x9e, 0x81, 0x90, 0x47, 0xe9, 0x59, + 0x4d, 0xa9, 0xe9, 0xb8, 0x9b, 0x5e, 0x40, 0xa2, 0x5d, 0xfd, 0x78, 0x93, 0x24, 0x4e, 0xde, 0x53, + 0x53, 0xdd, 0x9e, 0x8a, 0xda, 0x41, 0xe2, 0x35, 0x49, 0xc7, 0x03, 0xef, 0x3c, 0xe8, 0x81, 0xd8, + 0xdd, 0x24, 0x4d, 0xa7, 0xe3, 0xb9, 0x9f, 0xe8, 0xf6, 0x5c, 0x3b, 0xf1, 0xfc, 0x29, 0x2f, 0x48, + 0xe2, 0x24, 0xca, 0x3e, 0x64, 0xff, 0x8a, 0x05, 0xc3, 0xd3, 0x37, 0x56, 0xa7, 0xdb, 0xc9, 0xe6, + 0x6c, 0x18, 0x6c, 0x78, 0x0d, 0xf4, 0x1c, 0x0c, 0xba, 0x7e, 0x3b, 0x4e, 0x48, 0x74, 0xd5, 0x69, + 0x92, 0x71, 0xeb, 0x9c, 0xf5, 0x64, 0x6d, 0xe6, 0xe4, 0x37, 0xf7, 0x26, 0xde, 0x72, 0x7b, 0x6f, + 0x62, 0x70, 0x56, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x0c, 0x06, 0xa2, 0xd0, 0x27, 0xd3, 0xf8, 0xea, + 0x78, 0x89, 0x3d, 0x32, 0x2a, 0x1e, 0x19, 0xc0, 0xbc, 0x19, 0x4b, 0x38, 0x45, 0x6d, 0x45, 0xe1, + 0x86, 0xe7, 0x93, 0xf1, 0x72, 0x1a, 0x75, 0x85, 0x37, 0x63, 0x09, 0xb7, 0xff, 0xb8, 0x04, 0x30, + 0xdd, 0x6a, 0xad, 0x44, 0xe1, 0x4d, 0xe2, 0x26, 0xe8, 0x43, 0x50, 0xa5, 0xc3, 0x5c, 0x77, 0x12, + 0x87, 0x75, 0x6c, 0xf0, 0xfc, 0x8f, 0x4f, 0xf2, 0xb7, 0x9e, 0x34, 0xdf, 0x5a, 0x4f, 0x32, 0x8a, + 0x3d, 0xb9, 0xfd, 0xcc, 0xe4, 0xf2, 0x3a, 0x7d, 0x7e, 0x89, 0x24, 0xce, 0x0c, 0x12, 0xcc, 0x40, + 0xb7, 0x61, 0x45, 0x15, 0x05, 0xd0, 0x17, 0xb7, 0x88, 0xcb, 0xde, 0x61, 0xf0, 0xfc, 0xe2, 0xe4, + 0x51, 0x66, 0xf3, 0xa4, 0xee, 0xf9, 0x6a, 0x8b, 0xb8, 0x33, 0x43, 0x82, 0x73, 0x1f, 0xfd, 0x87, + 0x19, 0x1f, 0xb4, 0x0d, 0xfd, 0x71, 0xe2, 0x24, 0xed, 0x98, 0x0d, 0xc5, 0xe0, 0xf9, 0xab, 0x85, + 0x71, 0x64, 0x54, 0x67, 0x46, 0x04, 0xcf, 0x7e, 0xfe, 0x1f, 0x0b, 0x6e, 0xf6, 0x9f, 0x5a, 0x30, + 0xa2, 0x91, 0x17, 0xbd, 0x38, 0x41, 0x3f, 0xd3, 0x31, 0xb8, 0x93, 0xbd, 0x0d, 0x2e, 0x7d, 0x9a, + 0x0d, 0xed, 0x09, 0xc1, 0xac, 0x2a, 0x5b, 0x8c, 0x81, 0x6d, 0x42, 0xc5, 0x4b, 0x48, 0x33, 0x1e, + 0x2f, 0x9d, 0x2b, 0x3f, 0x39, 0x78, 0xfe, 0x52, 0x51, 0xef, 0x39, 0x33, 0x2c, 0x98, 0x56, 0x16, + 0x28, 0x79, 0xcc, 0xb9, 0xd8, 0x7f, 0x35, 0x6c, 0xbe, 0x1f, 0x1d, 0x70, 0xf4, 0x0c, 0x0c, 0xc6, + 0x61, 0x3b, 0x72, 0x09, 0x26, 0xad, 0x30, 0x1e, 0xb7, 0xce, 0x95, 0xe9, 0xd4, 0xa3, 0x93, 0x7a, + 0x55, 0x37, 0x63, 0x13, 0x07, 0x7d, 0xde, 0x82, 0xa1, 0x3a, 0x89, 0x13, 0x2f, 0x60, 0xfc, 0x65, + 0xe7, 0xd7, 0x8e, 0xdc, 0x79, 0xd9, 0x38, 0xa7, 0x89, 0xcf, 0x9c, 0x12, 0x2f, 0x32, 0x64, 0x34, + 0xc6, 0x38, 0xc5, 0x9f, 0x2e, 0xce, 0x3a, 0x89, 0xdd, 0xc8, 0x6b, 0xd1, 0xff, 0x62, 0xf9, 0xa8, + 0xc5, 0x39, 0xa7, 0x41, 0xd8, 0xc4, 0x43, 0x01, 0x54, 0xe8, 0xe2, 0x8b, 0xc7, 0xfb, 0x58, 0xff, + 0x17, 0x8e, 0xd6, 0x7f, 0x31, 0xa8, 0x74, 0x5d, 0xeb, 0xd1, 0xa7, 0xff, 0x62, 0xcc, 0xd9, 0xa0, + 0xcf, 0x59, 0x30, 0x2e, 0x84, 0x03, 0x26, 0x7c, 0x40, 0x6f, 0x6c, 0x7a, 0x09, 0xf1, 0xbd, 0x38, + 0x19, 0xaf, 0xb0, 0x3e, 0x4c, 0xf5, 0x36, 0xb7, 0xe6, 0xa3, 0xb0, 0xdd, 0xba, 0xe2, 0x05, 0xf5, + 0x99, 0x73, 0x82, 0xd3, 0xf8, 0x6c, 0x17, 0xc2, 0xb8, 0x2b, 0x4b, 0xf4, 0x25, 0x0b, 0xce, 0x04, + 0x4e, 0x93, 0xc4, 0x2d, 0x87, 0x7e, 0x5a, 0x0e, 0x9e, 0xf1, 0x1d, 0x77, 0x8b, 0xf5, 0xa8, 0xff, + 0xee, 0x7a, 0x64, 0x8b, 0x1e, 0x9d, 0xb9, 0xda, 0x95, 0x34, 0xde, 0x87, 0x2d, 0xfa, 0x9a, 0x05, + 0x63, 0x61, 0xd4, 0xda, 0x74, 0x02, 0x52, 0x97, 0xd0, 0x78, 0x7c, 0x80, 0x2d, 0xbd, 0x0f, 0x1e, + 0xed, 0x13, 0x2d, 0x67, 0xc9, 0x2e, 0x85, 0x81, 0x97, 0x84, 0xd1, 0x2a, 0x49, 0x12, 0x2f, 0x68, + 0xc4, 0x33, 0xa7, 0x6f, 0xef, 0x4d, 0x8c, 0x75, 0x60, 0xe1, 0xce, 0xfe, 0xa0, 0x9f, 0x85, 0xc1, + 0x78, 0x37, 0x70, 0x6f, 0x78, 0x41, 0x3d, 0xbc, 0x15, 0x8f, 0x57, 0x8b, 0x58, 0xbe, 0xab, 0x8a, + 0xa0, 0x58, 0x80, 0x9a, 0x01, 0x36, 0xb9, 0xe5, 0x7f, 0x38, 0x3d, 0x95, 0x6a, 0x45, 0x7f, 0x38, + 0x3d, 0x99, 0xf6, 0x61, 0x8b, 0x7e, 0xd1, 0x82, 0xe1, 0xd8, 0x6b, 0x04, 0x4e, 0xd2, 0x8e, 0xc8, + 0x15, 0xb2, 0x1b, 0x8f, 0x03, 0xeb, 0xc8, 0xe5, 0x23, 0x8e, 0x8a, 0x41, 0x72, 0xe6, 0xb4, 0xe8, + 0xe3, 0xb0, 0xd9, 0x1a, 0xe3, 0x34, 0xdf, 0xbc, 0x85, 0xa6, 0xa7, 0xf5, 0x60, 0xb1, 0x0b, 0x4d, + 0x4f, 0xea, 0xae, 0x2c, 0xd1, 0x4f, 0xc3, 0x09, 0xde, 0xa4, 0x46, 0x36, 0x1e, 0x1f, 0x62, 0x82, + 0xf6, 0xd4, 0xed, 0xbd, 0x89, 0x13, 0xab, 0x19, 0x18, 0xee, 0xc0, 0x46, 0xaf, 0xc2, 0x44, 0x8b, + 0x44, 0x4d, 0x2f, 0x59, 0x0e, 0xfc, 0x5d, 0x29, 0xbe, 0xdd, 0xb0, 0x45, 0xea, 0xa2, 0x3b, 0xf1, + 0xf8, 0xf0, 0x39, 0xeb, 0xc9, 0xea, 0xcc, 0xdb, 0x45, 0x37, 0x27, 0x56, 0xf6, 0x47, 0xc7, 0x07, + 0xd1, 0x43, 0xbf, 0x6f, 0xc1, 0x19, 0x43, 0xca, 0xae, 0x92, 0x68, 0xdb, 0x73, 0xc9, 0xb4, 0xeb, + 0x86, 0xed, 0x20, 0x89, 0xc7, 0x47, 0xd8, 0x30, 0xae, 0x1f, 0x87, 0xcc, 0x4f, 0xb3, 0xd2, 0xf3, + 0xb2, 0x2b, 0x4a, 0x8c, 0xf7, 0xe9, 0xa9, 0xfd, 0x6f, 0x4a, 0x70, 0x22, 0x6b, 0x01, 0xa0, 0x7f, + 0x60, 0xc1, 0xe8, 0xcd, 0x5b, 0xc9, 0x5a, 0xb8, 0x45, 0x82, 0x78, 0x66, 0x97, 0xca, 0x69, 0xa6, + 0xfb, 0x06, 0xcf, 0xbb, 0xc5, 0xda, 0x1a, 0x93, 0x97, 0xd3, 0x5c, 0x2e, 0x04, 0x49, 0xb4, 0x3b, + 0xf3, 0xb0, 0x78, 0xa7, 0xd1, 0xcb, 0x37, 0xd6, 0x4c, 0x28, 0xce, 0x76, 0xea, 0xcc, 0x67, 0x2c, + 0x38, 0x95, 0x47, 0x02, 0x9d, 0x80, 0xf2, 0x16, 0xd9, 0xe5, 0x96, 0x28, 0xa6, 0x3f, 0xd1, 0xcb, + 0x50, 0xd9, 0x76, 0xfc, 0x36, 0x11, 0x66, 0xda, 0xfc, 0xd1, 0x5e, 0x44, 0xf5, 0x0c, 0x73, 0xaa, + 0xef, 0x2a, 0x3d, 0x6f, 0xd9, 0x7f, 0x58, 0x86, 0x41, 0xe3, 0xa3, 0xdd, 0x03, 0xd3, 0x33, 0x4c, + 0x99, 0x9e, 0x4b, 0x85, 0xcd, 0xb7, 0xae, 0xb6, 0xe7, 0xad, 0x8c, 0xed, 0xb9, 0x5c, 0x1c, 0xcb, + 0x7d, 0x8d, 0x4f, 0x94, 0x40, 0x2d, 0x6c, 0xd1, 0x6d, 0x08, 0xb5, 0x61, 0xfa, 0x8a, 0xf8, 0x84, + 0xcb, 0x92, 0xdc, 0xcc, 0xf0, 0xed, 0xbd, 0x89, 0x9a, 0xfa, 0x8b, 0x35, 0x23, 0xfb, 0x3b, 0x16, + 0x9c, 0x32, 0xfa, 0x38, 0x1b, 0x06, 0x75, 0x8f, 0x7d, 0xda, 0x73, 0xd0, 0x97, 0xec, 0xb6, 0xe4, + 0x56, 0x47, 0x8d, 0xd4, 0xda, 0x6e, 0x8b, 0x60, 0x06, 0xa1, 0x3b, 0x96, 0x26, 0x89, 0x63, 0xa7, + 0x41, 0xb2, 0x9b, 0x9b, 0x25, 0xde, 0x8c, 0x25, 0x1c, 0x45, 0x80, 0x7c, 0x27, 0x4e, 0xd6, 0x22, + 0x27, 0x88, 0x19, 0xf9, 0x35, 0xaf, 0x49, 0xc4, 0x00, 0xff, 0x7f, 0xbd, 0xcd, 0x18, 0xfa, 0xc4, + 0xcc, 0x43, 0xb7, 0xf7, 0x26, 0xd0, 0x62, 0x07, 0x25, 0x9c, 0x43, 0xdd, 0xfe, 0x92, 0x05, 0x0f, + 0xe5, 0x0b, 0x18, 0xf4, 0x04, 0xf4, 0xf3, 0x7d, 0xae, 0x78, 0x3b, 0xfd, 0x49, 0x58, 0x2b, 0x16, + 0x50, 0x34, 0x05, 0x35, 0xa5, 0xf0, 0xc4, 0x3b, 0x8e, 0x09, 0xd4, 0x9a, 0xd6, 0x92, 0x1a, 0x87, + 0x0e, 0x1a, 0xfd, 0x23, 0x4c, 0x50, 0x35, 0x68, 0x6c, 0x63, 0xc8, 0x20, 0xf6, 0xb7, 0x2d, 0x78, + 0x5b, 0x2f, 0x62, 0xef, 0xf8, 0xfa, 0xb8, 0x0a, 0xa7, 0xeb, 0x64, 0xc3, 0x69, 0xfb, 0x49, 0x9a, + 0xa3, 0xe8, 0xf4, 0xa3, 0xe2, 0xe1, 0xd3, 0x73, 0x79, 0x48, 0x38, 0xff, 0x59, 0xfb, 0xbf, 0x58, + 0x30, 0x6a, 0xbc, 0xd6, 0x3d, 0xd8, 0x3a, 0x05, 0xe9, 0xad, 0xd3, 0x42, 0x61, 0xcb, 0xb4, 0xcb, + 0xde, 0xe9, 0x73, 0x16, 0x9c, 0x31, 0xb0, 0x96, 0x9c, 0xc4, 0xdd, 0xbc, 0xb0, 0xd3, 0x8a, 0x48, + 0x1c, 0xd3, 0x29, 0xf5, 0xa8, 0x21, 0x8e, 0x67, 0x06, 0x05, 0x85, 0xf2, 0x15, 0xb2, 0xcb, 0x65, + 0xf3, 0x53, 0x50, 0xe5, 0x6b, 0x2e, 0x8c, 0xc4, 0x47, 0x52, 0xef, 0xb6, 0x2c, 0xda, 0xb1, 0xc2, + 0x40, 0x36, 0xf4, 0x33, 0x99, 0x4b, 0x65, 0x10, 0x35, 0x13, 0x80, 0x7e, 0xf7, 0xeb, 0xac, 0x05, + 0x0b, 0x88, 0x1d, 0xa7, 0xba, 0xb3, 0x12, 0x11, 0x36, 0x1f, 0xea, 0x17, 0x3d, 0xe2, 0xd7, 0x63, + 0xba, 0xad, 0x73, 0x82, 0x20, 0x4c, 0xc4, 0x0e, 0xcd, 0xd8, 0xd6, 0x4d, 0xeb, 0x66, 0x6c, 0xe2, + 0x50, 0xa6, 0xbe, 0xb3, 0x4e, 0x7c, 0x3e, 0xa2, 0x82, 0xe9, 0x22, 0x6b, 0xc1, 0x02, 0x62, 0xdf, + 0x2e, 0xb1, 0x0d, 0xa4, 0x92, 0x68, 0xe4, 0x5e, 0x78, 0x1f, 0xa2, 0x94, 0x0a, 0x58, 0x29, 0x4e, + 0x1e, 0x93, 0xee, 0x1e, 0x88, 0xd7, 0x32, 0x5a, 0x00, 0x17, 0xca, 0x75, 0x7f, 0x2f, 0xc4, 0xc7, + 0xca, 0x30, 0x91, 0x7e, 0xa0, 0x43, 0x89, 0xd0, 0x2d, 0xaf, 0xc1, 0x28, 0xeb, 0x8f, 0x32, 0xf0, + 0xb1, 0x89, 0xd7, 0x45, 0x0e, 0x97, 0x8e, 0x53, 0x0e, 0x9b, 0x6a, 0xa2, 0x7c, 0x80, 0x9a, 0x78, + 0x42, 0x8d, 0x7a, 0x5f, 0x46, 0xe6, 0xa5, 0x55, 0xe5, 0x39, 0xe8, 0x8b, 0x13, 0xd2, 0x1a, 0xaf, + 0xa4, 0xc5, 0xec, 0x6a, 0x42, 0x5a, 0x98, 0x41, 0xd0, 0xbb, 0x61, 0x34, 0x71, 0xa2, 0x06, 0x49, + 0x22, 0xb2, 0xed, 0x31, 0xdf, 0x25, 0xdb, 0xcf, 0xd6, 0x66, 0x4e, 0x52, 0xab, 0x6b, 0x8d, 0x81, + 0xb0, 0x04, 0xe1, 0x2c, 0xae, 0xfd, 0xdf, 0x4b, 0xf0, 0x70, 0xfa, 0x13, 0x68, 0xc5, 0xf8, 0xde, + 0x94, 0x62, 0x7c, 0x87, 0xa9, 0x18, 0xef, 0xec, 0x4d, 0xbc, 0xb5, 0xcb, 0x63, 0x3f, 0x30, 0x7a, + 0x13, 0xcd, 0x67, 0x3e, 0xc2, 0x54, 0xfa, 0x23, 0xdc, 0xd9, 0x9b, 0x78, 0xb4, 0xcb, 0x3b, 0x66, + 0xbe, 0xd2, 0x13, 0xd0, 0x1f, 0x11, 0x27, 0x0e, 0x03, 0xf1, 0x9d, 0xd4, 0xd7, 0xc4, 0xac, 0x15, + 0x0b, 0xa8, 0xfd, 0xad, 0x5a, 0x76, 0xb0, 0xe7, 0xb9, 0x3f, 0x36, 0x8c, 0x90, 0x07, 0x7d, 0x6c, + 0xd7, 0xc6, 0x25, 0xcb, 0x95, 0xa3, 0xad, 0x42, 0xaa, 0x45, 0x14, 0xe9, 0x99, 0x2a, 0xfd, 0x6a, + 0xb4, 0x09, 0x33, 0x16, 0x68, 0x07, 0xaa, 0xae, 0xdc, 0x4c, 0x95, 0x8a, 0x70, 0x3b, 0x8a, 0xad, + 0x94, 0xe6, 0x38, 0x44, 0xc5, 0xbd, 0xda, 0x81, 0x29, 0x6e, 0x88, 0x40, 0xb9, 0xe1, 0x25, 0xe2, + 0xb3, 0x1e, 0x71, 0xbb, 0x3c, 0xef, 0x19, 0xaf, 0x38, 0x40, 0x75, 0xd0, 0xbc, 0x97, 0x60, 0x4a, + 0x1f, 0x7d, 0xca, 0x82, 0xc1, 0xd8, 0x6d, 0xae, 0x44, 0xe1, 0xb6, 0x57, 0x27, 0x91, 0xb0, 0x31, + 0x8f, 0x28, 0xd9, 0x56, 0x67, 0x97, 0x24, 0x41, 0xcd, 0x97, 0xbb, 0x2f, 0x34, 0x04, 0x9b, 0x7c, + 0xe9, 0xde, 0xeb, 0x61, 0xf1, 0xee, 0x73, 0xc4, 0x65, 0x2b, 0x4e, 0xee, 0x99, 0xd9, 0x4c, 0x39, + 0xb2, 0xcd, 0x3d, 0xd7, 0x76, 0xb7, 0xe8, 0x7a, 0xd3, 0x1d, 0x7a, 0xeb, 0xed, 0xbd, 0x89, 0x87, + 0x67, 0xf3, 0x79, 0xe2, 0x6e, 0x9d, 0x61, 0x03, 0xd6, 0x6a, 0xfb, 0x3e, 0x26, 0xaf, 0xb6, 0x09, + 0xf3, 0x88, 0x15, 0x30, 0x60, 0x2b, 0x9a, 0x60, 0x66, 0xc0, 0x0c, 0x08, 0x36, 0xf9, 0xa2, 0x57, + 0xa1, 0xbf, 0xe9, 0x24, 0x91, 0xb7, 0x23, 0xdc, 0x60, 0x47, 0xdc, 0x05, 0x2d, 0x31, 0x5a, 0x9a, + 0x39, 0x53, 0xf4, 0xbc, 0x11, 0x0b, 0x46, 0xa8, 0x09, 0x95, 0x26, 0x89, 0x1a, 0x64, 0xbc, 0x5a, + 0x84, 0xcb, 0x7f, 0x89, 0x92, 0xd2, 0x0c, 0x6b, 0xd4, 0xb8, 0x62, 0x6d, 0x98, 0x73, 0x41, 0x2f, + 0x43, 0x35, 0x26, 0x3e, 0x71, 0xa9, 0x79, 0x54, 0x63, 0x1c, 0x7f, 0xa2, 0x47, 0x53, 0x91, 0xda, + 0x25, 0xab, 0xe2, 0x51, 0xbe, 0xc0, 0xe4, 0x3f, 0xac, 0x48, 0xd2, 0x01, 0x6c, 0xf9, 0xed, 0x86, + 0x17, 0x8c, 0x43, 0x11, 0x03, 0xb8, 0xc2, 0x68, 0x65, 0x06, 0x90, 0x37, 0x62, 0xc1, 0xc8, 0xfe, + 0x6f, 0x16, 0xa0, 0xb4, 0x50, 0xbb, 0x07, 0x36, 0xf1, 0xab, 0x69, 0x9b, 0x78, 0xb1, 0x48, 0xa3, + 0xa5, 0x8b, 0x59, 0xfc, 0x9b, 0x35, 0xc8, 0xa8, 0x83, 0xab, 0x24, 0x4e, 0x48, 0xfd, 0x4d, 0x11, + 0xfe, 0xa6, 0x08, 0x7f, 0x53, 0x84, 0x2b, 0x11, 0xbe, 0x9e, 0x11, 0xe1, 0xef, 0x31, 0x56, 0xbd, + 0x3e, 0x5f, 0x7f, 0x45, 0x1d, 0xc0, 0x9b, 0x3d, 0x30, 0x10, 0xa8, 0x24, 0xb8, 0xbc, 0xba, 0x7c, + 0x35, 0x57, 0x66, 0xbf, 0x92, 0x96, 0xd9, 0x47, 0x65, 0xf1, 0xff, 0x82, 0x94, 0xfe, 0x7d, 0x0b, + 0xde, 0x9e, 0x96, 0x5e, 0x72, 0xe6, 0x2c, 0x34, 0x82, 0x30, 0x22, 0x73, 0xde, 0xc6, 0x06, 0x89, + 0x48, 0xe0, 0x92, 0x58, 0xf9, 0x76, 0xac, 0x6e, 0xbe, 0x1d, 0xf4, 0x2c, 0x0c, 0xdd, 0x8c, 0xc3, + 0x60, 0x25, 0xf4, 0x02, 0x21, 0x82, 0xe8, 0x8e, 0xe3, 0xc4, 0xed, 0xbd, 0x89, 0x21, 0x3a, 0xa2, + 0xb2, 0x1d, 0xa7, 0xb0, 0xd0, 0x2c, 0x8c, 0xdd, 0x7c, 0x75, 0xc5, 0x49, 0x0c, 0x6f, 0x82, 0xdc, + 0xf7, 0xb3, 0xf3, 0xa8, 0xcb, 0x2f, 0x66, 0x80, 0xb8, 0x13, 0xdf, 0xfe, 0xbb, 0x25, 0x78, 0x24, + 0xf3, 0x22, 0xa1, 0xef, 0x87, 0xed, 0x84, 0xee, 0x89, 0xd0, 0x57, 0x2c, 0x38, 0xd1, 0x4c, 0x3b, + 0x2c, 0x62, 0xe1, 0xee, 0x7e, 0x5f, 0x61, 0x3a, 0x22, 0xe3, 0x11, 0x99, 0x19, 0x17, 0x23, 0x74, + 0x22, 0x03, 0x88, 0x71, 0x47, 0x5f, 0xd0, 0xcb, 0x50, 0x6b, 0x3a, 0x3b, 0xd7, 0x5a, 0x75, 0x27, + 0x91, 0xdb, 0xd1, 0xee, 0x5e, 0x84, 0x76, 0xe2, 0xf9, 0x93, 0x3c, 0x72, 0x63, 0x72, 0x21, 0x48, + 0x96, 0xa3, 0xd5, 0x24, 0xf2, 0x82, 0x06, 0x77, 0x72, 0x2e, 0x49, 0x32, 0x58, 0x53, 0xb4, 0xbf, + 0x6c, 0x65, 0x95, 0x94, 0x1a, 0x9d, 0xc8, 0x49, 0x48, 0x63, 0x17, 0x7d, 0x18, 0x2a, 0x74, 0xdf, + 0x28, 0x47, 0xe5, 0x46, 0x91, 0x9a, 0xd3, 0xf8, 0x12, 0x5a, 0x89, 0xd2, 0x7f, 0x31, 0xe6, 0x4c, + 0xed, 0xaf, 0xd4, 0xb2, 0xc6, 0x02, 0x3b, 0x9b, 0x3f, 0x0f, 0xd0, 0x08, 0xd7, 0x48, 0xb3, 0xe5, + 0xd3, 0x61, 0xb1, 0xd8, 0x01, 0x8f, 0x72, 0x95, 0xcc, 0x2b, 0x08, 0x36, 0xb0, 0xd0, 0x2f, 0x59, + 0x00, 0x0d, 0x39, 0xe7, 0xa5, 0x21, 0x70, 0xad, 0xc8, 0xd7, 0xd1, 0x2b, 0x4a, 0xf7, 0x45, 0x31, + 0xc4, 0x06, 0x73, 0xf4, 0xf3, 0x16, 0x54, 0x13, 0xd9, 0x7d, 0xae, 0x1a, 0xd7, 0x8a, 0xec, 0x89, + 0x7c, 0x69, 0x6d, 0x13, 0xa9, 0x21, 0x51, 0x7c, 0xd1, 0x2f, 0x58, 0x00, 0xf1, 0x6e, 0xe0, 0xae, + 0x84, 0xbe, 0xe7, 0xee, 0x0a, 0x8d, 0x79, 0xbd, 0x50, 0x77, 0x8e, 0xa2, 0x3e, 0x33, 0x42, 0x47, + 0x43, 0xff, 0xc7, 0x06, 0x67, 0xf4, 0x51, 0xa8, 0xc6, 0x62, 0xba, 0x09, 0x1d, 0xb9, 0x56, 0xac, + 0x53, 0x89, 0xd3, 0x16, 0xe2, 0x55, 0xfc, 0xc3, 0x8a, 0x27, 0xfa, 0xdb, 0x16, 0x8c, 0xb6, 0xd2, + 0x6e, 0x42, 0xa1, 0x0e, 0x8b, 0x93, 0x01, 0x19, 0x37, 0x24, 0xf7, 0xb6, 0x64, 0x1a, 0x71, 0xb6, + 0x17, 0x54, 0x02, 0xea, 0x19, 0xbc, 0xdc, 0xe2, 0x2e, 0xcb, 0x01, 0x2d, 0x01, 0xe7, 0xb3, 0x40, + 0xdc, 0x89, 0x8f, 0x56, 0xe0, 0x14, 0xed, 0xdd, 0x2e, 0x37, 0x3f, 0xa5, 0x7a, 0x89, 0x99, 0x32, + 0xac, 0xce, 0x9c, 0x15, 0x33, 0x84, 0x9d, 0x75, 0x64, 0x71, 0x70, 0xee, 0x93, 0xe8, 0x0f, 0x2d, + 0x38, 0xeb, 0x31, 0x35, 0x60, 0x3a, 0xec, 0xb5, 0x46, 0x10, 0x07, 0xed, 0xa4, 0x50, 0x59, 0xd1, + 0x4d, 0xfd, 0xcc, 0xbc, 0x4d, 0xbc, 0xc1, 0xd9, 0x85, 0x7d, 0xba, 0x84, 0xf7, 0xed, 0x30, 0xfa, + 0x49, 0x18, 0x96, 0xeb, 0x62, 0x85, 0x8a, 0x60, 0xa6, 0x68, 0x6b, 0x33, 0x63, 0xb7, 0xf7, 0x26, + 0x86, 0xd7, 0x4c, 0x00, 0x4e, 0xe3, 0xd9, 0xff, 0xb6, 0x9c, 0x3a, 0x25, 0x52, 0x3e, 0x4c, 0x26, + 0x6e, 0x5c, 0xe9, 0xff, 0x91, 0xd2, 0xb3, 0x50, 0x71, 0xa3, 0xbc, 0x4b, 0x5a, 0xdc, 0xa8, 0xa6, + 0x18, 0x1b, 0xcc, 0xa9, 0x51, 0x3a, 0xe6, 0x64, 0x3d, 0xa5, 0x42, 0x02, 0xbe, 0x5c, 0x64, 0x97, + 0x3a, 0xcf, 0xf4, 0x1e, 0x11, 0x5d, 0x1b, 0xeb, 0x00, 0xe1, 0xce, 0x2e, 0xa1, 0x8f, 0x40, 0x2d, + 0x52, 0x91, 0x2d, 0xe5, 0x22, 0xb6, 0x6a, 0x72, 0xda, 0x88, 0xee, 0xa8, 0x03, 0x20, 0x1d, 0xc3, + 0xa2, 0x39, 0xda, 0x7f, 0x90, 0x3e, 0x18, 0x33, 0x64, 0x47, 0x0f, 0x87, 0x7e, 0x9f, 0xb7, 0x60, + 0x30, 0x0a, 0x7d, 0xdf, 0x0b, 0x1a, 0x54, 0xce, 0x09, 0x65, 0xfd, 0x81, 0x63, 0xd1, 0x97, 0x42, + 0xa0, 0x31, 0xcb, 0x1a, 0x6b, 0x9e, 0xd8, 0xec, 0x80, 0xfd, 0xa7, 0x16, 0x8c, 0x77, 0x93, 0xc7, + 0x88, 0xc0, 0x5b, 0xa5, 0xb0, 0x51, 0x43, 0xb1, 0x1c, 0xcc, 0x11, 0x9f, 0x28, 0xb7, 0x79, 0x75, + 0xe6, 0x71, 0xf1, 0x9a, 0x6f, 0x5d, 0xe9, 0x8e, 0x8a, 0xf7, 0xa3, 0x83, 0x5e, 0x82, 0x13, 0xc6, + 0x7b, 0xc5, 0x6a, 0x60, 0x6a, 0x33, 0x93, 0xd4, 0x00, 0x9a, 0xce, 0xc0, 0xee, 0xec, 0x4d, 0x3c, + 0x94, 0x6d, 0x13, 0x0a, 0xa3, 0x83, 0x8e, 0xfd, 0xeb, 0xa5, 0xec, 0xd7, 0x52, 0xba, 0xfe, 0x0d, + 0xab, 0xc3, 0x9b, 0xf0, 0xbe, 0xe3, 0xd0, 0xaf, 0xcc, 0xef, 0xa0, 0xc2, 0x30, 0xba, 0xe3, 0xdc, + 0xc7, 0x63, 0x7b, 0xfb, 0xdf, 0xf5, 0xc1, 0x3e, 0x3d, 0xeb, 0xc1, 0x78, 0x3f, 0xf4, 0x39, 0xea, + 0x67, 0x2d, 0x75, 0x60, 0xc6, 0xd7, 0x70, 0xfd, 0xb8, 0xc6, 0x9e, 0xef, 0x9f, 0x62, 0x1e, 0x3a, + 0xa2, 0xbc, 0xe8, 0xe9, 0xa3, 0x39, 0xf4, 0x55, 0x2b, 0x7d, 0xe4, 0xc7, 0x83, 0x1a, 0xbd, 0x63, + 0xeb, 0x93, 0x71, 0x8e, 0xc8, 0x3b, 0xa6, 0x4f, 0x9f, 0xba, 0x9d, 0x30, 0x4e, 0x02, 0x6c, 0x78, + 0x81, 0xe3, 0x7b, 0xaf, 0xd1, 0xdd, 0x51, 0x85, 0x29, 0x78, 0x66, 0x31, 0x5d, 0x54, 0xad, 0xd8, + 0xc0, 0x38, 0xf3, 0xff, 0xc3, 0xa0, 0xf1, 0xe6, 0x39, 0x11, 0x2f, 0xa7, 0xcc, 0x88, 0x97, 0x9a, + 0x11, 0xa8, 0x72, 0xe6, 0x3d, 0x70, 0x22, 0xdb, 0xc1, 0xc3, 0x3c, 0x6f, 0xff, 0xef, 0x81, 0xec, + 0x19, 0xdc, 0x1a, 0x89, 0x9a, 0xb4, 0x6b, 0x6f, 0x3a, 0xb6, 0xde, 0x74, 0x6c, 0xbd, 0xe9, 0xd8, + 0x32, 0xcf, 0x26, 0x84, 0xd3, 0x66, 0xe0, 0x1e, 0x39, 0x6d, 0x52, 0x6e, 0xa8, 0x6a, 0xe1, 0x6e, + 0x28, 0xfb, 0x53, 0x1d, 0x9e, 0xfb, 0xb5, 0x88, 0x10, 0x14, 0x42, 0x25, 0x08, 0xeb, 0x44, 0xda, + 0xb8, 0x97, 0x8b, 0x31, 0xd8, 0xae, 0x86, 0x75, 0x23, 0x5c, 0x9c, 0xfe, 0x8b, 0x31, 0xe7, 0x63, + 0xdf, 0xae, 0x40, 0xca, 0x9c, 0xe4, 0xdf, 0xfd, 0xc7, 0x60, 0x20, 0x22, 0xad, 0xf0, 0x1a, 0x5e, + 0x14, 0xba, 0x4c, 0x67, 0x94, 0xf0, 0x66, 0x2c, 0xe1, 0x54, 0xe7, 0xb5, 0x9c, 0x64, 0x53, 0x28, + 0x33, 0xa5, 0xf3, 0x56, 0x9c, 0x64, 0x13, 0x33, 0x08, 0x7a, 0x0f, 0x8c, 0x24, 0xa9, 0xa3, 0x70, + 0x71, 0xe4, 0xfb, 0x90, 0xc0, 0x1d, 0x49, 0x1f, 0x94, 0xe3, 0x0c, 0x36, 0x7a, 0x15, 0xfa, 0x36, + 0x89, 0xdf, 0x14, 0x9f, 0x7e, 0xb5, 0x38, 0x5d, 0xc3, 0xde, 0xf5, 0x12, 0xf1, 0x9b, 0x5c, 0x12, + 0xd2, 0x5f, 0x98, 0xb1, 0xa2, 0xf3, 0xbe, 0xb6, 0xd5, 0x8e, 0x93, 0xb0, 0xe9, 0xbd, 0x26, 0x3d, + 0x9d, 0xef, 0x2b, 0x98, 0xf1, 0x15, 0x49, 0x9f, 0xbb, 0x94, 0xd4, 0x5f, 0xac, 0x39, 0xb3, 0x7e, + 0xd4, 0xbd, 0x88, 0x4d, 0x99, 0x5d, 0xe1, 0xb0, 0x2c, 0xba, 0x1f, 0x73, 0x92, 0x3e, 0xef, 0x87, + 0xfa, 0x8b, 0x35, 0x67, 0xb4, 0xab, 0xd6, 0xdf, 0x20, 0xeb, 0xc3, 0xb5, 0x82, 0xfb, 0xc0, 0xd7, + 0x5e, 0xee, 0x3a, 0x7c, 0x1c, 0x2a, 0xee, 0xa6, 0x13, 0x25, 0xe3, 0x43, 0x6c, 0xd2, 0xa8, 0x59, + 0x3c, 0x4b, 0x1b, 0x31, 0x87, 0xa1, 0x47, 0xa1, 0x1c, 0x91, 0x0d, 0x16, 0x9d, 0x6c, 0xc4, 0x45, + 0x61, 0xb2, 0x81, 0x69, 0xbb, 0xfd, 0xab, 0xa5, 0xb4, 0xd9, 0x96, 0x7e, 0x6f, 0x3e, 0xdb, 0xdd, + 0x76, 0x14, 0x4b, 0xf7, 0x97, 0x31, 0xdb, 0x59, 0x33, 0x96, 0x70, 0xf4, 0x71, 0x0b, 0x06, 0x6e, + 0xc6, 0x61, 0x10, 0x90, 0x44, 0xa8, 0xc8, 0xeb, 0x05, 0x0f, 0xc5, 0x65, 0x4e, 0x5d, 0xf7, 0x41, + 0x34, 0x60, 0xc9, 0x97, 0x76, 0x97, 0xec, 0xb8, 0x7e, 0xbb, 0xde, 0x11, 0xea, 0x72, 0x81, 0x37, + 0x63, 0x09, 0xa7, 0xa8, 0x5e, 0xc0, 0x51, 0xfb, 0xd2, 0xa8, 0x0b, 0x81, 0x40, 0x15, 0x70, 0xfb, + 0xfb, 0x03, 0x70, 0x3a, 0x77, 0x71, 0x50, 0x83, 0x8a, 0x99, 0x2c, 0x17, 0x3d, 0x9f, 0xc8, 0x20, + 0x2f, 0x66, 0x50, 0x5d, 0x57, 0xad, 0xd8, 0xc0, 0x40, 0x3f, 0x07, 0xd0, 0x72, 0x22, 0xa7, 0x49, + 0x94, 0x7b, 0xfa, 0xc8, 0x76, 0x0b, 0xed, 0xc7, 0x8a, 0xa4, 0xa9, 0xb7, 0xe8, 0xaa, 0x29, 0xc6, + 0x06, 0x4b, 0xf4, 0x1c, 0x0c, 0x46, 0xc4, 0x27, 0x4e, 0xcc, 0x82, 0xdb, 0xb3, 0x99, 0x3a, 0x58, + 0x83, 0xb0, 0x89, 0x87, 0x9e, 0x50, 0xf1, 0x70, 0x99, 0xb8, 0xa0, 0x74, 0x4c, 0x1c, 0x7a, 0xdd, + 0x82, 0x91, 0x0d, 0xcf, 0x27, 0x9a, 0xbb, 0xc8, 0xab, 0x59, 0x3e, 0xfa, 0x4b, 0x5e, 0x34, 0xe9, + 0x6a, 0x09, 0x99, 0x6a, 0x8e, 0x71, 0x86, 0x3d, 0xfd, 0xcc, 0xdb, 0x24, 0x62, 0xa2, 0xb5, 0x3f, + 0xfd, 0x99, 0xaf, 0xf3, 0x66, 0x2c, 0xe1, 0x68, 0x1a, 0x46, 0x5b, 0x4e, 0x1c, 0xcf, 0x46, 0xa4, + 0x4e, 0x82, 0xc4, 0x73, 0x7c, 0x9e, 0xf5, 0x52, 0xd5, 0xc1, 0xe2, 0x2b, 0x69, 0x30, 0xce, 0xe2, + 0xa3, 0xf7, 0xc3, 0xc3, 0xdc, 0xff, 0xb3, 0xe4, 0xc5, 0xb1, 0x17, 0x34, 0xf4, 0x34, 0x10, 0x6e, + 0xb0, 0x09, 0x41, 0xea, 0xe1, 0x85, 0x7c, 0x34, 0xdc, 0xed, 0x79, 0xf4, 0x14, 0x54, 0xe3, 0x2d, + 0xaf, 0x35, 0x1b, 0xd5, 0x63, 0x76, 0xf6, 0x53, 0xd5, 0x4e, 0xd7, 0x55, 0xd1, 0x8e, 0x15, 0x06, + 0x72, 0x61, 0x88, 0x7f, 0x12, 0x1e, 0xd0, 0x27, 0xe4, 0xe3, 0xd3, 0x5d, 0xd5, 0xb4, 0x48, 0xe2, + 0x9c, 0xc4, 0xce, 0xad, 0x0b, 0xf2, 0x24, 0x8a, 0x1f, 0x9c, 0x5c, 0x37, 0xc8, 0xe0, 0x14, 0xd1, + 0xf4, 0x8e, 0x6d, 0xb0, 0x87, 0x1d, 0xdb, 0x73, 0x30, 0xb8, 0xd5, 0x5e, 0x27, 0x62, 0xe4, 0x85, + 0xd8, 0x52, 0xb3, 0xef, 0x8a, 0x06, 0x61, 0x13, 0x8f, 0xc5, 0x52, 0xb6, 0x3c, 0xf1, 0x2f, 0x1e, + 0x1f, 0x36, 0x62, 0x29, 0x57, 0x16, 0x64, 0x33, 0x36, 0x71, 0x68, 0xd7, 0xe8, 0x58, 0xac, 0x91, + 0x98, 0xa5, 0x4a, 0xd0, 0xe1, 0x52, 0x5d, 0x5b, 0x95, 0x00, 0xac, 0x71, 0xec, 0x5f, 0x2e, 0xa5, + 0xbd, 0x18, 0xa6, 0xc0, 0x41, 0x31, 0x15, 0x2b, 0xc9, 0x75, 0x27, 0x92, 0xc6, 0xc7, 0x11, 0x13, + 0x8d, 0x04, 0xdd, 0xeb, 0x4e, 0x64, 0x0a, 0x28, 0xc6, 0x00, 0x4b, 0x4e, 0xe8, 0x26, 0xf4, 0x25, + 0xbe, 0x53, 0x50, 0x66, 0xa2, 0xc1, 0x51, 0x3b, 0x95, 0x16, 0xa7, 0x63, 0xcc, 0x78, 0xa0, 0xb3, + 0x74, 0x27, 0xb5, 0x2e, 0x4f, 0xbd, 0xc4, 0xe6, 0x67, 0x3d, 0xc6, 0xac, 0xd5, 0xfe, 0xb3, 0xc1, + 0x1c, 0x1d, 0xa1, 0x94, 0x32, 0x3a, 0x0f, 0x40, 0x3f, 0xf1, 0x4a, 0x44, 0x36, 0xbc, 0x1d, 0x61, + 0x14, 0x29, 0x39, 0x74, 0x55, 0x41, 0xb0, 0x81, 0x25, 0x9f, 0x59, 0x6d, 0x6f, 0xd0, 0x67, 0x4a, + 0x9d, 0xcf, 0x70, 0x08, 0x36, 0xb0, 0xd0, 0xb3, 0xd0, 0xef, 0x35, 0x9d, 0x86, 0x0a, 0xca, 0x3d, + 0x4b, 0x05, 0xd0, 0x02, 0x6b, 0xb9, 0xb3, 0x37, 0x31, 0xa2, 0x3a, 0xc4, 0x9a, 0xb0, 0xc0, 0x45, + 0xbf, 0x6e, 0xc1, 0x90, 0x1b, 0x36, 0x9b, 0x61, 0xc0, 0xb7, 0xb2, 0x62, 0x5f, 0x7e, 0xf3, 0xb8, + 0x4c, 0x96, 0xc9, 0x59, 0x83, 0x19, 0xdf, 0x98, 0xab, 0x14, 0x4a, 0x13, 0x84, 0x53, 0xbd, 0x32, + 0xe5, 0x54, 0xe5, 0x00, 0x39, 0xf5, 0x1b, 0x16, 0x8c, 0xf1, 0x67, 0x8d, 0x1d, 0xb6, 0xc8, 0x16, + 0x0c, 0x8f, 0xf9, 0xb5, 0x3a, 0x9c, 0x0e, 0xca, 0xf1, 0xda, 0x01, 0xc7, 0x9d, 0x9d, 0x44, 0xf3, + 0x30, 0xb6, 0x11, 0x46, 0x2e, 0x31, 0x07, 0x42, 0x08, 0x59, 0x45, 0xe8, 0x62, 0x16, 0x01, 0x77, + 0x3e, 0x83, 0xae, 0xc3, 0x43, 0x46, 0xa3, 0x39, 0x0e, 0x5c, 0xce, 0x3e, 0x26, 0xa8, 0x3d, 0x74, + 0x31, 0x17, 0x0b, 0x77, 0x79, 0x3a, 0x2d, 0xd2, 0x6a, 0x3d, 0x88, 0xb4, 0x57, 0xe0, 0x11, 0xb7, + 0x73, 0x64, 0xb6, 0xe3, 0xf6, 0x7a, 0xcc, 0xa5, 0x6e, 0x75, 0xe6, 0x47, 0x04, 0x81, 0x47, 0x66, + 0xbb, 0x21, 0xe2, 0xee, 0x34, 0xd0, 0x87, 0xa1, 0x1a, 0x11, 0xf6, 0x55, 0x62, 0x91, 0x3a, 0x77, + 0x44, 0xcf, 0x83, 0xb6, 0xa6, 0x39, 0x59, 0xad, 0x47, 0x44, 0x43, 0x8c, 0x15, 0x47, 0x74, 0x0b, + 0x06, 0x5a, 0x4e, 0xe2, 0x6e, 0x8a, 0x84, 0xb9, 0x23, 0xfb, 0xc9, 0x15, 0x73, 0x76, 0xac, 0x61, + 0xa4, 0xd8, 0x73, 0x26, 0x58, 0x72, 0xa3, 0x96, 0x95, 0x1b, 0x36, 0x5b, 0x61, 0x40, 0x82, 0x44, + 0x8a, 0xfc, 0x11, 0x7e, 0xf6, 0x20, 0x5b, 0xb1, 0x81, 0x81, 0x56, 0xe0, 0x14, 0xf3, 0xc3, 0xdd, + 0xf0, 0x92, 0xcd, 0xb0, 0x9d, 0xc8, 0x6d, 0xa5, 0x90, 0xfd, 0xea, 0xf4, 0x69, 0x31, 0x07, 0x07, + 0xe7, 0x3e, 0x99, 0x55, 0x56, 0xa3, 0x77, 0xa7, 0xac, 0x4e, 0x1c, 0xac, 0xac, 0xce, 0xbc, 0x17, + 0xc6, 0x3a, 0x84, 0xc6, 0xa1, 0x9c, 0x6d, 0x73, 0xf0, 0x50, 0xfe, 0xf2, 0x3c, 0x94, 0xcb, 0xed, + 0x9f, 0x67, 0x62, 0xae, 0x8d, 0xed, 0x47, 0x0f, 0xee, 0x5b, 0x07, 0xca, 0x24, 0xd8, 0x16, 0xda, + 0xea, 0xe2, 0xd1, 0x66, 0xc9, 0x85, 0x60, 0x9b, 0x4b, 0x17, 0xe6, 0xa3, 0xba, 0x10, 0x6c, 0x63, + 0x4a, 0x1b, 0x7d, 0xd1, 0x4a, 0x99, 0xcf, 0xdc, 0xe9, 0xfb, 0xc1, 0x63, 0xd9, 0x6f, 0xf5, 0x6c, + 0x51, 0xdb, 0xff, 0xbe, 0x04, 0xe7, 0x0e, 0x22, 0xd2, 0xc3, 0xf0, 0x3d, 0x0e, 0xfd, 0x31, 0x8b, + 0xa2, 0x10, 0xe2, 0x7f, 0x90, 0xae, 0x0a, 0x1e, 0x57, 0xf1, 0x0a, 0x16, 0x20, 0xe4, 0x43, 0xb9, + 0xe9, 0xb4, 0x84, 0x2f, 0x70, 0xe1, 0xa8, 0xb9, 0x69, 0xf4, 0xbf, 0xe3, 0x2f, 0x39, 0x2d, 0x3e, + 0x3d, 0x8d, 0x06, 0x4c, 0xd9, 0xa0, 0x04, 0x2a, 0x4e, 0x14, 0x39, 0xf2, 0xc8, 0xfe, 0x4a, 0x31, + 0xfc, 0xa6, 0x29, 0x49, 0x7e, 0xe2, 0x99, 0x6a, 0xc2, 0x9c, 0x99, 0xfd, 0xd9, 0x81, 0x54, 0x22, + 0x13, 0x8b, 0xc3, 0x88, 0xa1, 0x5f, 0xb8, 0x00, 0xad, 0xa2, 0x53, 0x02, 0x79, 0xa6, 0x30, 0xdb, + 0x5d, 0x8b, 0x7a, 0x0b, 0x82, 0x15, 0xfa, 0x8c, 0xc5, 0xaa, 0x1a, 0xc8, 0xec, 0x30, 0xb1, 0xa7, + 0x3d, 0x9e, 0x22, 0x0b, 0x66, 0xad, 0x04, 0xd9, 0x88, 0x4d, 0xee, 0xa2, 0x3a, 0x09, 0xb3, 0xe5, + 0x3b, 0xab, 0x93, 0x30, 0xdb, 0x5c, 0xc2, 0xd1, 0x4e, 0x4e, 0xbc, 0x45, 0x01, 0x99, 0xf1, 0x3d, + 0x44, 0x58, 0x7c, 0xd5, 0x82, 0x31, 0x2f, 0x7b, 0x70, 0x2e, 0x76, 0x80, 0x37, 0x8a, 0xf1, 0xd7, + 0x75, 0x9e, 0xcb, 0x2b, 0xc3, 0xa1, 0x03, 0x84, 0x3b, 0x3b, 0x83, 0xea, 0xd0, 0xe7, 0x05, 0x1b, + 0xa1, 0x30, 0x97, 0x66, 0x8e, 0xd6, 0xa9, 0x85, 0x60, 0x23, 0xd4, 0xab, 0x99, 0xfe, 0xc3, 0x8c, + 0x3a, 0x5a, 0x84, 0x53, 0x32, 0x97, 0xe5, 0x92, 0x17, 0x27, 0x61, 0xb4, 0xbb, 0xe8, 0x35, 0xbd, + 0x84, 0x99, 0x3a, 0xe5, 0x99, 0x71, 0xaa, 0x89, 0x70, 0x0e, 0x1c, 0xe7, 0x3e, 0x85, 0x5e, 0x83, + 0x01, 0x79, 0x58, 0x5d, 0x2d, 0x62, 0x37, 0xdd, 0x39, 0xff, 0xd5, 0x64, 0x5a, 0x15, 0xa7, 0xd5, + 0x92, 0xa1, 0xfd, 0xfa, 0x20, 0x74, 0x9e, 0xa9, 0xa7, 0x0f, 0xd0, 0xad, 0x7b, 0x7d, 0x80, 0x4e, + 0xb7, 0x46, 0xb1, 0x3e, 0xfb, 0x2e, 0x60, 0x6e, 0x0b, 0xae, 0xfa, 0x5c, 0x73, 0x37, 0x70, 0x31, + 0xe3, 0x81, 0x22, 0xe8, 0xdf, 0x24, 0x8e, 0x9f, 0x6c, 0x16, 0x73, 0x04, 0x73, 0x89, 0xd1, 0xca, + 0x26, 0xa0, 0xf1, 0x56, 0x2c, 0x38, 0xa1, 0x1d, 0x18, 0xd8, 0xe4, 0x13, 0x40, 0xec, 0x56, 0x96, + 0x8e, 0x3a, 0xb8, 0xa9, 0x59, 0xa5, 0x3f, 0xb7, 0x68, 0xc0, 0x92, 0x1d, 0x0b, 0xd6, 0x32, 0xc2, + 0x49, 0xf8, 0xd2, 0x2d, 0x2e, 0xf7, 0xae, 0xf7, 0x58, 0x92, 0x0f, 0xc1, 0x50, 0x44, 0xdc, 0x30, + 0x70, 0x3d, 0x9f, 0xd4, 0xa7, 0xe5, 0xf1, 0xca, 0x61, 0x52, 0xae, 0x98, 0xf7, 0x02, 0x1b, 0x34, + 0x70, 0x8a, 0x22, 0xfa, 0xb4, 0x05, 0x23, 0x2a, 0x0d, 0x9b, 0x7e, 0x10, 0x22, 0xdc, 0xe8, 0x8b, + 0x05, 0x25, 0x7d, 0x33, 0x9a, 0x33, 0xe8, 0xf6, 0xde, 0xc4, 0x48, 0xba, 0x0d, 0x67, 0xf8, 0xa2, + 0x97, 0x00, 0xc2, 0x75, 0x1e, 0x91, 0x35, 0x9d, 0x08, 0x9f, 0xfa, 0x61, 0x5e, 0x75, 0x84, 0xa7, + 0x6e, 0x4a, 0x0a, 0xd8, 0xa0, 0x86, 0xae, 0x00, 0xf0, 0x65, 0xb3, 0xb6, 0xdb, 0x92, 0x5b, 0x1a, + 0x99, 0x33, 0x07, 0xab, 0x0a, 0x72, 0x67, 0x6f, 0xa2, 0xd3, 0xc7, 0xc9, 0xc2, 0x4e, 0x8c, 0xc7, + 0xd1, 0xcf, 0xc2, 0x40, 0xdc, 0x6e, 0x36, 0x1d, 0xe5, 0x71, 0x2f, 0x30, 0x19, 0x94, 0xd3, 0x35, + 0x44, 0x11, 0x6f, 0xc0, 0x92, 0x23, 0xba, 0x49, 0x85, 0x6a, 0x2c, 0x9c, 0xaf, 0x6c, 0x15, 0x71, + 0x9b, 0x80, 0x7b, 0x9e, 0xde, 0x29, 0x4d, 0x7c, 0x9c, 0x83, 0x73, 0x67, 0x6f, 0xe2, 0xa1, 0x74, + 0xfb, 0x62, 0x28, 0xd2, 0x33, 0x73, 0x69, 0xa2, 0xcb, 0xb2, 0x2a, 0x13, 0x7d, 0x6d, 0x59, 0x2c, + 0xe4, 0x49, 0x5d, 0x95, 0x89, 0x35, 0x77, 0x1f, 0x33, 0xf3, 0x61, 0xb4, 0x04, 0x27, 0xdd, 0x30, + 0x48, 0xa2, 0xd0, 0xf7, 0x79, 0x55, 0x32, 0xbe, 0xbb, 0xe4, 0x1e, 0xf9, 0xb7, 0x8a, 0x6e, 0x9f, + 0x9c, 0xed, 0x44, 0xc1, 0x79, 0xcf, 0xd9, 0x41, 0xfa, 0x74, 0x4c, 0x0c, 0xce, 0xb3, 0x30, 0x44, + 0x76, 0x12, 0x12, 0x05, 0x8e, 0x7f, 0x0d, 0x2f, 0x4a, 0x5f, 0x34, 0x5b, 0x03, 0x17, 0x8c, 0x76, + 0x9c, 0xc2, 0x42, 0xb6, 0x72, 0xa9, 0x18, 0x29, 0xc7, 0xdc, 0xa5, 0x22, 0x1d, 0x28, 0xf6, 0x37, + 0xca, 0x29, 0x83, 0xec, 0xbe, 0x9c, 0xc5, 0xb1, 0xda, 0x36, 0xb2, 0x08, 0x10, 0x03, 0x88, 0x8d, + 0x46, 0x91, 0x9c, 0x55, 0x6d, 0x9b, 0x65, 0x93, 0x11, 0x4e, 0xf3, 0x45, 0x5b, 0x50, 0xd9, 0x0c, + 0xe3, 0x44, 0x6e, 0x3f, 0x8e, 0xb8, 0xd3, 0xb9, 0x14, 0xc6, 0x09, 0xb3, 0x22, 0xd4, 0x6b, 0xd3, + 0x96, 0x18, 0x73, 0x1e, 0x74, 0x0f, 0x1a, 0x6f, 0x3a, 0x51, 0x3d, 0x9e, 0x65, 0x05, 0x02, 0xfa, + 0x98, 0xf9, 0xa0, 0x8c, 0xc5, 0x55, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0xe7, 0x56, 0xea, 0xc0, 0xe2, + 0x06, 0x8b, 0xf6, 0xde, 0x26, 0x01, 0x95, 0x06, 0x66, 0x7c, 0xd9, 0x4f, 0x66, 0x72, 0x67, 0xdf, + 0xde, 0xad, 0x56, 0xdf, 0x2d, 0x4a, 0x61, 0x92, 0x91, 0x30, 0x42, 0xd1, 0x3e, 0x66, 0xa5, 0x93, + 0xa0, 0x4b, 0x45, 0xec, 0x4b, 0xcc, 0x42, 0x00, 0x07, 0xe6, 0x53, 0xdb, 0x5f, 0xb4, 0x60, 0x60, + 0xc6, 0x71, 0xb7, 0xc2, 0x8d, 0x0d, 0xf4, 0x14, 0x54, 0xeb, 0xed, 0xc8, 0xcc, 0xc7, 0x56, 0x9e, + 0x8d, 0x39, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0xfa, 0x1b, 0x8e, 0x2b, 0xcb, 0x01, 0x94, 0xf9, 0xd4, + 0xbf, 0xc8, 0x5a, 0xb0, 0x80, 0xd0, 0xe1, 0x6f, 0x3a, 0x3b, 0xf2, 0xe1, 0xec, 0x69, 0xc9, 0x92, + 0x06, 0x61, 0x13, 0xcf, 0xfe, 0xd7, 0x16, 0x8c, 0xcf, 0x38, 0xb1, 0xe7, 0x4e, 0xb7, 0x93, 0xcd, + 0x19, 0x2f, 0x59, 0x6f, 0xbb, 0x5b, 0x24, 0xe1, 0x65, 0x23, 0x68, 0x2f, 0xdb, 0x31, 0x5d, 0x81, + 0x6a, 0x3b, 0xa8, 0x7a, 0x79, 0x4d, 0xb4, 0x63, 0x85, 0x81, 0x5e, 0x83, 0xc1, 0x96, 0x13, 0xc7, + 0xb7, 0xc2, 0xa8, 0x8e, 0xc9, 0x46, 0x31, 0x85, 0x65, 0x56, 0x89, 0x1b, 0x91, 0x04, 0x93, 0x0d, + 0x11, 0x59, 0xa0, 0xe9, 0x63, 0x93, 0x99, 0xfd, 0x4b, 0x16, 0x9c, 0x9a, 0x21, 0x4e, 0x44, 0x22, + 0x56, 0x87, 0x46, 0xbd, 0x08, 0x7a, 0x15, 0xaa, 0x09, 0x6d, 0xa1, 0x3d, 0xb2, 0x8a, 0xed, 0x11, + 0x8b, 0x09, 0x58, 0x13, 0xc4, 0xb1, 0x62, 0x63, 0x7f, 0xde, 0x82, 0x47, 0xf2, 0xfa, 0x32, 0xeb, + 0x87, 0xed, 0xfa, 0xfd, 0xe8, 0xd0, 0xdf, 0xb1, 0x60, 0x88, 0x9d, 0xb3, 0xce, 0x91, 0xc4, 0xf1, + 0xfc, 0x8e, 0x1a, 0x78, 0x56, 0x8f, 0x35, 0xf0, 0xce, 0x41, 0xdf, 0x66, 0xd8, 0x24, 0xd9, 0x18, + 0x81, 0x4b, 0x61, 0x93, 0x60, 0x06, 0x41, 0xcf, 0xd0, 0x49, 0xe8, 0x05, 0x89, 0x43, 0x97, 0xa3, + 0xf4, 0x7d, 0x8f, 0xf2, 0x09, 0xa8, 0x9a, 0xb1, 0x89, 0x63, 0xff, 0xab, 0x1a, 0x0c, 0x88, 0x80, + 0x96, 0x9e, 0xcb, 0x98, 0x48, 0x17, 0x45, 0xa9, 0xab, 0x8b, 0x22, 0x86, 0x7e, 0x97, 0x15, 0xe3, + 0x14, 0x96, 0xf0, 0x95, 0x42, 0x22, 0xa0, 0x78, 0x7d, 0x4f, 0xdd, 0x2d, 0xfe, 0x1f, 0x0b, 0x56, + 0xe8, 0x0b, 0x16, 0x8c, 0xba, 0x61, 0x10, 0x10, 0x57, 0x9b, 0x69, 0x7d, 0x45, 0x04, 0xba, 0xcc, + 0xa6, 0x89, 0xea, 0x43, 0xbe, 0x0c, 0x00, 0x67, 0xd9, 0xa3, 0x17, 0x60, 0x98, 0x8f, 0xd9, 0xf5, + 0x94, 0xc3, 0x5e, 0x97, 0x46, 0x33, 0x81, 0x38, 0x8d, 0x8b, 0x26, 0xf9, 0xc1, 0x87, 0x28, 0x42, + 0xd6, 0xaf, 0xfd, 0x9a, 0x46, 0xf9, 0x31, 0x03, 0x03, 0x45, 0x80, 0x22, 0xb2, 0x11, 0x91, 0x78, + 0x53, 0x04, 0xfc, 0x30, 0x13, 0x71, 0xe0, 0xee, 0x0a, 0x10, 0xe0, 0x0e, 0x4a, 0x38, 0x87, 0x3a, + 0xda, 0x12, 0x7b, 0xe4, 0x6a, 0x11, 0xf2, 0x5c, 0x7c, 0xe6, 0xae, 0x5b, 0xe5, 0x09, 0xa8, 0x30, + 0xd5, 0xc5, 0x4c, 0xd3, 0x32, 0x4f, 0x7a, 0x63, 0x8a, 0x0d, 0xf3, 0x76, 0x34, 0x07, 0x27, 0x32, + 0x85, 0xdd, 0x62, 0xe1, 0x58, 0x57, 0x09, 0x4e, 0x99, 0x92, 0x70, 0x31, 0xee, 0x78, 0xc2, 0xf4, + 0x9f, 0x0c, 0x1e, 0xe0, 0x3f, 0xd9, 0x55, 0x61, 0xa5, 0xdc, 0xe5, 0xfd, 0x62, 0x21, 0x03, 0xd0, + 0x53, 0x0c, 0xe9, 0xe7, 0x32, 0x31, 0xa4, 0xc3, 0xac, 0x03, 0xd7, 0x8b, 0xe9, 0xc0, 0xe1, 0x03, + 0x46, 0xef, 0x67, 0x00, 0xe8, 0xff, 0xb2, 0x40, 0x7e, 0xd7, 0x59, 0xc7, 0xdd, 0x24, 0x74, 0xca, + 0xa0, 0xf7, 0xc0, 0x88, 0xf2, 0x02, 0x70, 0x93, 0xc8, 0x62, 0xb3, 0x46, 0x45, 0x03, 0xe0, 0x14, + 0x14, 0x67, 0xb0, 0xd1, 0x14, 0xd4, 0xe8, 0x38, 0xf1, 0x47, 0xb9, 0xde, 0x57, 0x9e, 0x86, 0xe9, + 0x95, 0x05, 0xf1, 0x94, 0xc6, 0x41, 0x21, 0x8c, 0xf9, 0x4e, 0x9c, 0xb0, 0x1e, 0xac, 0xee, 0x06, + 0xee, 0x5d, 0x96, 0xff, 0x60, 0x59, 0x34, 0x8b, 0x59, 0x42, 0xb8, 0x93, 0xb6, 0xfd, 0x1f, 0x2a, + 0x30, 0x9c, 0x92, 0x8c, 0x87, 0x34, 0x18, 0x9e, 0x82, 0xaa, 0xd4, 0xe1, 0xd9, 0x3a, 0x47, 0x4a, + 0xd1, 0x2b, 0x0c, 0xaa, 0xb4, 0xd6, 0xb5, 0x56, 0xcd, 0x1a, 0x38, 0x86, 0xc2, 0xc5, 0x26, 0x1e, + 0x13, 0xca, 0x89, 0x1f, 0xcf, 0xfa, 0x1e, 0x09, 0x12, 0xde, 0xcd, 0x62, 0x84, 0xf2, 0xda, 0xe2, + 0xaa, 0x49, 0x54, 0x0b, 0xe5, 0x0c, 0x00, 0x67, 0xd9, 0xa3, 0x4f, 0x5a, 0x30, 0xec, 0xdc, 0x8a, + 0x75, 0xc5, 0x68, 0x11, 0x2d, 0x7a, 0x44, 0x25, 0x95, 0x2a, 0x42, 0xcd, 0xbd, 0xd6, 0xa9, 0x26, + 0x9c, 0x66, 0x8a, 0xde, 0xb0, 0x00, 0x91, 0x1d, 0xe2, 0xca, 0x78, 0x56, 0xd1, 0x97, 0xfe, 0x22, + 0x36, 0xcb, 0x17, 0x3a, 0xe8, 0x72, 0xa9, 0xde, 0xd9, 0x8e, 0x73, 0xfa, 0x80, 0x2e, 0x03, 0xaa, + 0x7b, 0xb1, 0xb3, 0xee, 0x93, 0xd9, 0xb0, 0x29, 0x33, 0x3f, 0xc5, 0xe1, 0xeb, 0x19, 0x31, 0xce, + 0x68, 0xae, 0x03, 0x03, 0xe7, 0x3c, 0xc5, 0x66, 0x59, 0x14, 0xee, 0xec, 0x5e, 0x8b, 0x7c, 0xa6, + 0x25, 0xcc, 0x59, 0x26, 0xda, 0xb1, 0xc2, 0xb0, 0xff, 0xa2, 0xac, 0x96, 0xb2, 0x0e, 0xde, 0x76, + 0x8c, 0x20, 0x52, 0xeb, 0xee, 0x83, 0x48, 0x75, 0x10, 0x4c, 0x67, 0x3e, 0x73, 0x2a, 0xfd, 0xb1, + 0x74, 0x9f, 0xd2, 0x1f, 0x7f, 0xde, 0x4a, 0xd5, 0x12, 0x1b, 0x3c, 0xff, 0x52, 0xb1, 0x81, 0xe3, + 0x93, 0x3c, 0x40, 0x27, 0xa3, 0x57, 0x32, 0x71, 0x59, 0x4f, 0x41, 0x75, 0xc3, 0x77, 0x58, 0x05, + 0x0c, 0xb6, 0x50, 0x8d, 0xe0, 0xa1, 0x8b, 0xa2, 0x1d, 0x2b, 0x0c, 0x2a, 0xf5, 0x0d, 0xa2, 0x87, + 0x92, 0xda, 0xff, 0xa9, 0x0c, 0x83, 0x86, 0xc6, 0xcf, 0x35, 0xdf, 0xac, 0x07, 0xcc, 0x7c, 0x2b, + 0x1d, 0xc2, 0x7c, 0xfb, 0x39, 0xa8, 0xb9, 0x52, 0x1b, 0x15, 0x53, 0x1b, 0x3d, 0xab, 0xe3, 0xb4, + 0x42, 0x52, 0x4d, 0x58, 0xf3, 0x44, 0xf3, 0xa9, 0x14, 0xbb, 0x94, 0x5f, 0x20, 0x2f, 0x07, 0x4e, + 0x68, 0xb4, 0xce, 0x67, 0xb2, 0xe7, 0xd4, 0x95, 0x83, 0xcf, 0xa9, 0xed, 0xef, 0x58, 0xea, 0xe3, + 0xde, 0x83, 0x5a, 0x2a, 0x37, 0xd3, 0xb5, 0x54, 0x2e, 0x14, 0x32, 0xcc, 0x5d, 0x8a, 0xa8, 0x5c, + 0x85, 0x81, 0xd9, 0xb0, 0xd9, 0x74, 0x82, 0x3a, 0xfa, 0x51, 0x18, 0x70, 0xf9, 0x4f, 0xe1, 0x43, + 0x63, 0x27, 0xb1, 0x02, 0x8a, 0x25, 0x0c, 0x9d, 0x85, 0x3e, 0x27, 0x6a, 0x48, 0xbf, 0x19, 0x8b, + 0x98, 0x9a, 0x8e, 0x1a, 0x31, 0x66, 0xad, 0xf6, 0x3f, 0xeb, 0x03, 0x16, 0xa8, 0xe0, 0x44, 0xa4, + 0xbe, 0x16, 0xb2, 0x92, 0xa6, 0xc7, 0x7a, 0x7e, 0xa9, 0x37, 0x75, 0x0f, 0xf2, 0x19, 0xa6, 0x71, + 0x8e, 0x55, 0xbe, 0xc7, 0xe7, 0x58, 0x5d, 0x8e, 0x26, 0xfb, 0x1e, 0xa0, 0xa3, 0x49, 0xfb, 0xb3, + 0x16, 0x20, 0x15, 0xdd, 0xa2, 0x63, 0x07, 0xa6, 0xa0, 0xa6, 0xe2, 0x5c, 0x84, 0x01, 0xa8, 0x45, + 0x84, 0x04, 0x60, 0x8d, 0xd3, 0xc3, 0x4e, 0xfe, 0x71, 0x29, 0xbf, 0xcb, 0xe9, 0xc0, 0x71, 0x26, + 0xf5, 0x85, 0x38, 0xb7, 0x7f, 0xb7, 0x04, 0x0f, 0x71, 0xd3, 0x61, 0xc9, 0x09, 0x9c, 0x06, 0x69, + 0xd2, 0x5e, 0xf5, 0x1a, 0x0d, 0xe2, 0xd2, 0x2d, 0xa4, 0x27, 0x03, 0xc1, 0x8f, 0xba, 0x76, 0xf9, + 0x9a, 0xe3, 0xab, 0x6c, 0x21, 0xf0, 0x12, 0xcc, 0x88, 0xa3, 0x18, 0xaa, 0xf2, 0xe2, 0x10, 0x21, + 0x8b, 0x0b, 0x62, 0xa4, 0xc4, 0x92, 0xd0, 0xb2, 0x04, 0x2b, 0x46, 0x54, 0x95, 0xfa, 0xa1, 0xbb, + 0x85, 0x49, 0x2b, 0xcc, 0xaa, 0xd2, 0x45, 0xd1, 0x8e, 0x15, 0x86, 0xdd, 0x84, 0x51, 0x39, 0x86, + 0xad, 0x2b, 0x64, 0x17, 0x93, 0x0d, 0xaa, 0x7f, 0x5c, 0xd9, 0x64, 0xdc, 0x65, 0xa2, 0xf4, 0xcf, + 0xac, 0x09, 0xc4, 0x69, 0x5c, 0x59, 0xe5, 0xb4, 0x94, 0x5f, 0xe5, 0xd4, 0xfe, 0x5d, 0x0b, 0xb2, + 0x0a, 0xd0, 0xa8, 0xe9, 0x68, 0xed, 0x5b, 0xd3, 0xf1, 0x10, 0x55, 0x11, 0x7f, 0x06, 0x06, 0x9d, + 0x84, 0x5a, 0x38, 0xdc, 0x1b, 0x51, 0xbe, 0xbb, 0x03, 0xab, 0xa5, 0xb0, 0xee, 0x6d, 0x78, 0xcc, + 0x0b, 0x61, 0x92, 0xb3, 0xff, 0xaa, 0x0f, 0xc6, 0x3a, 0xb2, 0xb4, 0xd0, 0xf3, 0x30, 0xa4, 0x86, + 0x42, 0xfa, 0xf9, 0x6a, 0x66, 0x68, 0xa5, 0x86, 0xe1, 0x14, 0x66, 0x0f, 0xeb, 0x61, 0x01, 0x4e, + 0x46, 0xe4, 0xd5, 0x36, 0x69, 0x93, 0xe9, 0x8d, 0x84, 0x44, 0xab, 0xc4, 0x0d, 0x83, 0x3a, 0xaf, + 0x3c, 0x5a, 0x9e, 0x79, 0xf8, 0xf6, 0xde, 0xc4, 0x49, 0xdc, 0x09, 0xc6, 0x79, 0xcf, 0xa0, 0x16, + 0x0c, 0xfb, 0xa6, 0x81, 0x2a, 0xf6, 0x45, 0x77, 0x65, 0xdb, 0xaa, 0x29, 0x91, 0x6a, 0xc6, 0x69, + 0x06, 0x69, 0x2b, 0xb7, 0x72, 0x9f, 0xac, 0xdc, 0x4f, 0x68, 0x2b, 0x97, 0x47, 0x56, 0x7c, 0xa0, + 0xe0, 0x2c, 0xbd, 0x5e, 0xcc, 0xdc, 0xa3, 0x18, 0xae, 0x2f, 0x42, 0x55, 0x46, 0x9d, 0xf5, 0x14, + 0xad, 0x65, 0xd2, 0xe9, 0x22, 0x40, 0x9f, 0x80, 0xb7, 0x5d, 0x88, 0x22, 0x63, 0x30, 0xaf, 0x86, + 0xc9, 0xb4, 0xef, 0x87, 0xb7, 0xa8, 0x4d, 0x70, 0x2d, 0x26, 0xc2, 0xf1, 0x64, 0xdf, 0x29, 0x41, + 0xce, 0x1e, 0x8e, 0xae, 0x47, 0x6d, 0x88, 0xa4, 0xd6, 0xe3, 0xe1, 0x8c, 0x11, 0xb4, 0xc3, 0x23, + 0xf3, 0xb8, 0xca, 0x7d, 0x7f, 0xd1, 0x7b, 0x50, 0x1d, 0xac, 0xa7, 0xc4, 0x91, 0x0a, 0xd8, 0x3b, + 0x0f, 0xa0, 0xed, 0x47, 0x91, 0x3a, 0xa2, 0x0e, 0xfe, 0xb5, 0x99, 0x89, 0x0d, 0x2c, 0xf4, 0x1c, + 0x0c, 0x7a, 0x41, 0x9c, 0x38, 0xbe, 0x7f, 0xc9, 0x0b, 0x12, 0xe1, 0x5b, 0x55, 0xb6, 0xc5, 0x82, + 0x06, 0x61, 0x13, 0xef, 0xcc, 0x3b, 0x8d, 0xef, 0x77, 0x98, 0xef, 0xbe, 0x09, 0x8f, 0xcc, 0x7b, + 0x89, 0x4a, 0x78, 0x52, 0xf3, 0x8d, 0x9a, 0x87, 0x2a, 0x81, 0xcf, 0xea, 0x9a, 0xc0, 0x67, 0x24, + 0x1c, 0x95, 0xd2, 0xf9, 0x51, 0xd9, 0x84, 0x23, 0xfb, 0x79, 0x38, 0x35, 0xef, 0x25, 0x17, 0x3d, + 0x9f, 0x1c, 0x92, 0x89, 0xfd, 0x3b, 0xfd, 0x30, 0x64, 0xa6, 0xee, 0x1e, 0x26, 0x07, 0xf1, 0xf3, + 0xd4, 0x02, 0x14, 0x6f, 0xe7, 0xa9, 0x63, 0xd3, 0x1b, 0x47, 0xce, 0x23, 0xce, 0x1f, 0x31, 0xc3, + 0x08, 0xd4, 0x3c, 0xb1, 0xd9, 0x01, 0x74, 0x0b, 0x2a, 0x1b, 0x2c, 0x21, 0xa6, 0x5c, 0x44, 0x6c, + 0x49, 0xde, 0x88, 0xea, 0xe5, 0xc8, 0x53, 0x6a, 0x38, 0x3f, 0xaa, 0xb8, 0xa3, 0x74, 0x96, 0xa5, + 0x11, 0xf8, 0x2c, 0xf2, 0x2b, 0x15, 0x46, 0x37, 0x95, 0x50, 0xb9, 0x0b, 0x95, 0x90, 0x12, 0xd0, + 0xfd, 0xf7, 0x49, 0x40, 0xb3, 0xe4, 0xa6, 0x64, 0x93, 0x99, 0x95, 0x22, 0x53, 0x63, 0x80, 0x0d, + 0x82, 0x91, 0xdc, 0x94, 0x02, 0xe3, 0x2c, 0x3e, 0xfa, 0xa8, 0x12, 0xf1, 0xd5, 0x22, 0xdc, 0xd2, + 0xe6, 0x8c, 0x3e, 0x6e, 0xe9, 0xfe, 0xd9, 0x12, 0x8c, 0xcc, 0x07, 0xed, 0x95, 0xf9, 0x95, 0xf6, + 0xba, 0xef, 0xb9, 0x57, 0xc8, 0x2e, 0x15, 0xe1, 0x5b, 0x64, 0x77, 0x61, 0x4e, 0xac, 0x20, 0x35, + 0x67, 0xae, 0xd0, 0x46, 0xcc, 0x61, 0x54, 0x18, 0x6d, 0x78, 0x41, 0x83, 0x44, 0xad, 0xc8, 0x13, + 0x1e, 0x63, 0x43, 0x18, 0x5d, 0xd4, 0x20, 0x6c, 0xe2, 0x51, 0xda, 0xe1, 0xad, 0x80, 0x44, 0x59, + 0xfb, 0x7a, 0x99, 0x36, 0x62, 0x0e, 0xa3, 0x48, 0x49, 0xd4, 0x16, 0x0e, 0x19, 0x03, 0x69, 0x8d, + 0x36, 0x62, 0x0e, 0xa3, 0x2b, 0x3d, 0x6e, 0xaf, 0xb3, 0xd0, 0x9d, 0x4c, 0x5a, 0xc8, 0x2a, 0x6f, + 0xc6, 0x12, 0x4e, 0x51, 0xb7, 0xc8, 0xee, 0x1c, 0xdd, 0x8c, 0x67, 0x32, 0xdd, 0xae, 0xf0, 0x66, + 0x2c, 0xe1, 0xac, 0x36, 0x6a, 0x7a, 0x38, 0x7e, 0xe0, 0x6a, 0xa3, 0xa6, 0xbb, 0xdf, 0x65, 0x5b, + 0xff, 0x6b, 0x16, 0x0c, 0x99, 0x01, 0x77, 0xa8, 0x91, 0xb1, 0x85, 0x97, 0x3b, 0x4a, 0x6b, 0xbf, + 0x3b, 0xef, 0xda, 0xc9, 0x86, 0x97, 0x84, 0xad, 0xf8, 0x69, 0x12, 0x34, 0xbc, 0x80, 0xb0, 0x80, + 0x08, 0x1e, 0xa8, 0x97, 0x8a, 0xe6, 0x9b, 0x0d, 0xeb, 0xe4, 0x2e, 0x8c, 0x69, 0xfb, 0x06, 0x8c, + 0x75, 0xa4, 0x37, 0xf6, 0x60, 0x82, 0x1c, 0x98, 0x5c, 0x6e, 0x63, 0x18, 0xa4, 0x84, 0x65, 0x7d, + 0xae, 0x59, 0x18, 0xe3, 0x0b, 0x89, 0x72, 0x5a, 0x75, 0x37, 0x49, 0x53, 0xa5, 0xac, 0xb2, 0xe3, + 0x89, 0xeb, 0x59, 0x20, 0xee, 0xc4, 0xb7, 0x3f, 0x67, 0xc1, 0x70, 0x2a, 0xe3, 0xb4, 0x20, 0x63, + 0x89, 0xad, 0xb4, 0x90, 0xc5, 0x7f, 0xb2, 0x20, 0xf8, 0x32, 0x53, 0xa6, 0x7a, 0xa5, 0x69, 0x10, + 0x36, 0xf1, 0xec, 0x2f, 0x96, 0xa0, 0x2a, 0x63, 0x68, 0x7a, 0xe8, 0xca, 0x67, 0x2c, 0x18, 0x56, + 0x47, 0x42, 0xcc, 0x87, 0x57, 0x2a, 0x22, 0xa5, 0x86, 0xf6, 0x40, 0x79, 0x01, 0x82, 0x8d, 0x50, + 0x5b, 0xee, 0xd8, 0x64, 0x86, 0xd3, 0xbc, 0xd1, 0x75, 0x80, 0x78, 0x37, 0x4e, 0x48, 0xd3, 0xf0, + 0x26, 0xda, 0xc6, 0x8a, 0x9b, 0x74, 0xc3, 0x88, 0xd0, 0xf5, 0x75, 0x35, 0xac, 0x93, 0x55, 0x85, + 0xa9, 0x4d, 0x28, 0xdd, 0x86, 0x0d, 0x4a, 0xf6, 0x3f, 0x29, 0xc1, 0x89, 0x6c, 0x97, 0xd0, 0x07, + 0x60, 0x48, 0x72, 0x37, 0x76, 0x9d, 0x32, 0x02, 0x68, 0x08, 0x1b, 0xb0, 0x3b, 0x7b, 0x13, 0x13, + 0x9d, 0x57, 0x98, 0x4e, 0x9a, 0x28, 0x38, 0x45, 0x8c, 0x9f, 0xcb, 0x89, 0x03, 0xe4, 0x99, 0xdd, + 0xe9, 0x56, 0x4b, 0x1c, 0xae, 0x19, 0xe7, 0x72, 0x26, 0x14, 0x67, 0xb0, 0xd1, 0x0a, 0x9c, 0x32, + 0x5a, 0xae, 0x12, 0xaf, 0xb1, 0xb9, 0x1e, 0x46, 0x72, 0x07, 0x76, 0x56, 0x87, 0xf6, 0x75, 0xe2, + 0xe0, 0xdc, 0x27, 0xa9, 0xb6, 0x77, 0x9d, 0x96, 0xe3, 0x7a, 0xc9, 0xae, 0x70, 0x8f, 0x2a, 0xd9, + 0x34, 0x2b, 0xda, 0xb1, 0xc2, 0xb0, 0x97, 0xa0, 0xaf, 0xc7, 0x19, 0xd4, 0x93, 0xe5, 0xff, 0x22, + 0x54, 0x29, 0x39, 0x69, 0xde, 0x15, 0x41, 0x32, 0x84, 0xaa, 0xbc, 0x10, 0x0a, 0xd9, 0x50, 0xf6, + 0x1c, 0x79, 0xf4, 0xa9, 0x5e, 0x6b, 0x21, 0x8e, 0xdb, 0x6c, 0x33, 0x4d, 0x81, 0xe8, 0x71, 0x28, + 0x93, 0x9d, 0x56, 0xf6, 0x8c, 0xf3, 0xc2, 0x4e, 0xcb, 0x8b, 0x48, 0x4c, 0x91, 0xc8, 0x4e, 0x0b, + 0x9d, 0x81, 0x92, 0x57, 0x17, 0x4a, 0x0a, 0x04, 0x4e, 0x69, 0x61, 0x0e, 0x97, 0xbc, 0xba, 0xbd, + 0x03, 0x35, 0x75, 0x03, 0x15, 0xda, 0x92, 0xb2, 0xdb, 0x2a, 0x22, 0xe8, 0x4d, 0xd2, 0xed, 0x22, + 0xb5, 0xdb, 0x00, 0x3a, 0x5d, 0xb5, 0x28, 0xf9, 0x72, 0x0e, 0xfa, 0xdc, 0x50, 0x94, 0x05, 0xa8, + 0x6a, 0x32, 0x4c, 0x68, 0x33, 0x88, 0x7d, 0x03, 0x46, 0xae, 0x04, 0xe1, 0x2d, 0x76, 0x51, 0x04, + 0xab, 0x8b, 0x48, 0x09, 0x6f, 0xd0, 0x1f, 0x59, 0x13, 0x81, 0x41, 0x31, 0x87, 0xa9, 0x8a, 0x6d, + 0xa5, 0x6e, 0x15, 0xdb, 0xec, 0x8f, 0x59, 0x30, 0xa4, 0xf2, 0xde, 0xe6, 0xb7, 0xb7, 0x28, 0xdd, + 0x46, 0x14, 0xb6, 0x5b, 0x59, 0xba, 0xec, 0xb2, 0x3b, 0xcc, 0x61, 0x66, 0x42, 0x68, 0xe9, 0x80, + 0x84, 0xd0, 0x73, 0xd0, 0xb7, 0xe5, 0x05, 0xf5, 0xec, 0xa5, 0x47, 0x57, 0xbc, 0xa0, 0x8e, 0x19, + 0x84, 0x76, 0xe1, 0x84, 0xea, 0x82, 0x54, 0x08, 0xcf, 0xc3, 0xd0, 0x7a, 0xdb, 0xf3, 0xeb, 0xb2, + 0xe0, 0x63, 0xc6, 0xa3, 0x32, 0x63, 0xc0, 0x70, 0x0a, 0x93, 0xee, 0xeb, 0xd6, 0xbd, 0xc0, 0x89, + 0x76, 0x57, 0xb4, 0x06, 0x52, 0x42, 0x69, 0x46, 0x41, 0xb0, 0x81, 0x65, 0xbf, 0x5e, 0x86, 0x91, + 0x74, 0xf6, 0x5f, 0x0f, 0xdb, 0xab, 0xc7, 0xa1, 0xc2, 0x12, 0x02, 0xb3, 0x9f, 0x96, 0xd7, 0x48, + 0xe4, 0x30, 0x14, 0x43, 0x3f, 0x2f, 0x8b, 0x52, 0xcc, 0x85, 0x61, 0xaa, 0x93, 0xca, 0x0f, 0xc3, + 0x42, 0x03, 0x45, 0x25, 0x16, 0xc1, 0x0a, 0x7d, 0xd2, 0x82, 0x81, 0xb0, 0x65, 0x56, 0xfa, 0x7a, + 0x7f, 0x91, 0x99, 0x91, 0x22, 0x5d, 0x4a, 0x58, 0xc4, 0xea, 0xd3, 0xcb, 0xcf, 0x21, 0x59, 0x9f, + 0x79, 0x17, 0x0c, 0x99, 0x98, 0x07, 0x19, 0xc5, 0x55, 0xd3, 0x28, 0xfe, 0x8c, 0x39, 0x29, 0x44, + 0xee, 0x67, 0x0f, 0xcb, 0xed, 0x1a, 0x54, 0x5c, 0x15, 0x3f, 0x71, 0x57, 0x65, 0x82, 0x55, 0x9d, + 0x12, 0x76, 0x36, 0xc5, 0xa9, 0xd9, 0xdf, 0xb1, 0x8c, 0xf9, 0x81, 0x49, 0xbc, 0x50, 0x47, 0x11, + 0x94, 0x1b, 0xdb, 0x5b, 0xc2, 0x14, 0xbd, 0x5c, 0xd0, 0xf0, 0xce, 0x6f, 0x6f, 0xe9, 0x39, 0x6e, + 0xb6, 0x62, 0xca, 0xac, 0x07, 0x67, 0x61, 0x2a, 0x45, 0xb8, 0x7c, 0x70, 0x8a, 0xb0, 0xfd, 0x46, + 0x09, 0xc6, 0x3a, 0x26, 0x15, 0x7a, 0x0d, 0x2a, 0x11, 0x7d, 0x4b, 0xf1, 0x7a, 0x8b, 0x85, 0x25, + 0xf5, 0xc6, 0x0b, 0x75, 0xad, 0x77, 0xd3, 0xed, 0x98, 0xb3, 0x44, 0x97, 0x01, 0xe9, 0x28, 0x1f, + 0xe5, 0xa9, 0xe4, 0xaf, 0xac, 0x42, 0x01, 0xa6, 0x3b, 0x30, 0x70, 0xce, 0x53, 0xe8, 0x85, 0xac, + 0xc3, 0xb3, 0x9c, 0x76, 0x67, 0xef, 0xe7, 0xbb, 0xb4, 0x7f, 0xab, 0x04, 0xc3, 0xa9, 0xc2, 0x6b, + 0xc8, 0x87, 0x2a, 0xf1, 0xd9, 0x59, 0x83, 0x54, 0x36, 0x47, 0x2d, 0xa3, 0xae, 0x14, 0xe4, 0x05, + 0x41, 0x17, 0x2b, 0x0e, 0x0f, 0x46, 0x84, 0xc0, 0xf3, 0x30, 0x24, 0x3b, 0xf4, 0x7e, 0xa7, 0xe9, + 0x8b, 0x01, 0x54, 0x73, 0xf4, 0x82, 0x01, 0xc3, 0x29, 0x4c, 0xfb, 0xf7, 0xca, 0x30, 0xce, 0x0f, + 0x67, 0xea, 0x6a, 0xe6, 0x2d, 0xc9, 0xfd, 0xd6, 0xdf, 0xd0, 0xe5, 0x11, 0xad, 0x22, 0xee, 0x0a, + 0xed, 0xc6, 0xa8, 0xa7, 0xc0, 0xb6, 0xaf, 0x64, 0x02, 0xdb, 0xb8, 0xd9, 0xdd, 0x38, 0xa6, 0x1e, + 0xfd, 0x60, 0x45, 0xba, 0xfd, 0xc3, 0x12, 0x8c, 0x66, 0xae, 0x84, 0x41, 0xaf, 0xa7, 0xab, 0x88, + 0x5b, 0x45, 0xf8, 0xd4, 0xf7, 0xbd, 0x25, 0xe4, 0x70, 0xb5, 0xc4, 0xef, 0xd3, 0x52, 0xb1, 0xbf, + 0x5d, 0x82, 0x91, 0xf4, 0x5d, 0x36, 0x0f, 0xe0, 0x48, 0xbd, 0x03, 0x6a, 0xec, 0xba, 0x06, 0x76, + 0x05, 0x33, 0x77, 0xc9, 0xf3, 0xca, 0xf8, 0xb2, 0x11, 0x6b, 0xf8, 0x03, 0x51, 0xa2, 0xdd, 0xfe, + 0xc7, 0x16, 0x9c, 0xe6, 0x6f, 0x99, 0x9d, 0x87, 0x7f, 0x33, 0x6f, 0x74, 0x5f, 0x2e, 0xb6, 0x83, + 0x99, 0xb2, 0x9e, 0x07, 0x8d, 0x2f, 0xbb, 0x31, 0x55, 0xf4, 0x36, 0x3d, 0x15, 0x1e, 0xc0, 0xce, + 0x1e, 0x6a, 0x32, 0xd8, 0xdf, 0x2e, 0x83, 0xbe, 0x24, 0x16, 0x79, 0x22, 0xcb, 0xb5, 0x90, 0xf2, + 0xa6, 0xab, 0xbb, 0x81, 0xab, 0xaf, 0xa3, 0xad, 0x66, 0x92, 0x5c, 0x7f, 0xd1, 0x82, 0x41, 0x2f, + 0xf0, 0x12, 0xcf, 0x61, 0xdb, 0xe8, 0x62, 0x6e, 0x7a, 0x54, 0xec, 0x16, 0x38, 0xe5, 0x30, 0x32, + 0xcf, 0x71, 0x14, 0x33, 0x6c, 0x72, 0x46, 0x1f, 0x12, 0xb1, 0xe7, 0xe5, 0xc2, 0xf2, 0xb3, 0xab, + 0x99, 0x80, 0xf3, 0x16, 0x35, 0xbc, 0x92, 0xa8, 0xa0, 0xb2, 0x06, 0x98, 0x92, 0x52, 0x95, 0xb2, + 0x95, 0x69, 0xcb, 0x9a, 0x31, 0x67, 0x64, 0xc7, 0x80, 0x3a, 0xc7, 0xe2, 0x90, 0x71, 0xbd, 0x53, + 0x50, 0x73, 0xda, 0x49, 0xd8, 0xa4, 0xc3, 0x24, 0x8e, 0x9a, 0x74, 0xe4, 0xb2, 0x04, 0x60, 0x8d, + 0x63, 0xbf, 0x5e, 0x81, 0x4c, 0xda, 0x29, 0xda, 0x31, 0x2f, 0x38, 0xb6, 0x8a, 0xbd, 0xe0, 0x58, + 0x75, 0x26, 0xef, 0x92, 0x63, 0xd4, 0x80, 0x4a, 0x6b, 0xd3, 0x89, 0xa5, 0x59, 0xfd, 0xa2, 0xda, + 0xc7, 0xd1, 0xc6, 0x3b, 0x7b, 0x13, 0x3f, 0xdd, 0x9b, 0xd7, 0x95, 0xce, 0xd5, 0x29, 0x5e, 0x2a, + 0x47, 0xb3, 0x66, 0x34, 0x30, 0xa7, 0x7f, 0x98, 0xbb, 0x2e, 0x3f, 0x2e, 0xee, 0xa5, 0xc0, 0x24, + 0x6e, 0xfb, 0x89, 0x98, 0x0d, 0x2f, 0x16, 0xb8, 0xca, 0x38, 0x61, 0x5d, 0x30, 0x81, 0xff, 0xc7, + 0x06, 0x53, 0xf4, 0x01, 0xa8, 0xc5, 0x89, 0x13, 0x25, 0x77, 0x99, 0xe2, 0xac, 0x4b, 0x9a, 0x49, + 0x22, 0x58, 0xd3, 0x43, 0x2f, 0xb1, 0x6a, 0xcf, 0x5e, 0xbc, 0x79, 0x97, 0x29, 0x23, 0xb2, 0x32, + 0xb4, 0xa0, 0x80, 0x0d, 0x6a, 0xe8, 0x3c, 0x00, 0x9b, 0xdb, 0x3c, 0xfe, 0xb0, 0xca, 0xbc, 0x4c, + 0x4a, 0x14, 0x62, 0x05, 0xc1, 0x06, 0x96, 0xfd, 0xe3, 0x90, 0xae, 0xf8, 0x81, 0x26, 0x64, 0x81, + 0x11, 0xee, 0x85, 0x66, 0xa9, 0x1f, 0xa9, 0x5a, 0x20, 0xbf, 0x61, 0x81, 0x59, 0x96, 0x04, 0xbd, + 0xca, 0xeb, 0x9f, 0x58, 0x45, 0x9c, 0x1c, 0x1a, 0x74, 0x27, 0x97, 0x9c, 0x56, 0xe6, 0x08, 0x5b, + 0x16, 0x41, 0x39, 0xf3, 0x4e, 0xa8, 0x4a, 0xe8, 0xa1, 0x8c, 0xba, 0x8f, 0xc2, 0x49, 0x99, 0x46, + 0x2a, 0xfd, 0xa6, 0xe2, 0xd4, 0xe9, 0x60, 0xd7, 0x8f, 0xf4, 0xe7, 0x94, 0xba, 0xf9, 0x73, 0x7a, + 0xb8, 0xe6, 0xfa, 0x37, 0x2d, 0x38, 0x97, 0xed, 0x40, 0xbc, 0x14, 0x06, 0x5e, 0x12, 0x46, 0xab, + 0x24, 0x49, 0xbc, 0xa0, 0xc1, 0xca, 0xbe, 0xdd, 0x72, 0x22, 0x59, 0x86, 0x9f, 0x09, 0xca, 0x1b, + 0x4e, 0x14, 0x60, 0xd6, 0x8a, 0x76, 0xa1, 0x9f, 0x07, 0xa9, 0x09, 0x6b, 0xfd, 0x88, 0x6b, 0x23, + 0x67, 0x38, 0xf4, 0x76, 0x81, 0x07, 0xc8, 0x61, 0xc1, 0xd0, 0xfe, 0x9e, 0x05, 0x68, 0x79, 0x9b, + 0x44, 0x91, 0x57, 0x37, 0xc2, 0xea, 0xd8, 0xfd, 0x4e, 0xc6, 0x3d, 0x4e, 0x66, 0x92, 0x73, 0xe6, + 0x7e, 0x27, 0xe3, 0x5f, 0xfe, 0xfd, 0x4e, 0xa5, 0xc3, 0xdd, 0xef, 0x84, 0x96, 0xe1, 0x74, 0x93, + 0x6f, 0x37, 0xf8, 0x9d, 0x29, 0x7c, 0xef, 0xa1, 0xf2, 0xf1, 0x1e, 0xb9, 0xbd, 0x37, 0x71, 0x7a, + 0x29, 0x0f, 0x01, 0xe7, 0x3f, 0x67, 0xbf, 0x13, 0x10, 0x8f, 0xa6, 0x9b, 0xcd, 0x8b, 0x55, 0xea, + 0xea, 0x7e, 0xb1, 0xbf, 0x5c, 0x81, 0xd1, 0x4c, 0x91, 0x66, 0xba, 0xd5, 0xeb, 0x0c, 0x8e, 0x3a, + 0xb2, 0xfe, 0xee, 0xec, 0x5e, 0x4f, 0xe1, 0x56, 0x01, 0x54, 0xbc, 0xa0, 0xd5, 0x4e, 0x8a, 0x49, + 0x07, 0xe6, 0x9d, 0x58, 0xa0, 0x04, 0x0d, 0x77, 0x31, 0xfd, 0x8b, 0x39, 0x9b, 0x22, 0x83, 0xb7, + 0x52, 0xc6, 0x78, 0xdf, 0x7d, 0x72, 0x07, 0x7c, 0x5c, 0x87, 0x52, 0x55, 0x8a, 0x70, 0x2c, 0x66, + 0x26, 0xcb, 0x71, 0x1f, 0xb5, 0x7f, 0xa3, 0x04, 0x83, 0xc6, 0x47, 0x43, 0xbf, 0x9a, 0x2e, 0xda, + 0x65, 0x15, 0xf7, 0x4a, 0x8c, 0xfe, 0xa4, 0x2e, 0xcb, 0xc5, 0x5f, 0xe9, 0x89, 0xce, 0x7a, 0x5d, + 0x77, 0xf6, 0x26, 0x4e, 0x64, 0x2a, 0x72, 0xa5, 0x6a, 0x78, 0x9d, 0xf9, 0x08, 0x8c, 0x66, 0xc8, + 0xe4, 0xbc, 0xf2, 0x9a, 0xf9, 0xca, 0x47, 0x76, 0x4b, 0x99, 0x43, 0xf6, 0x75, 0x3a, 0x64, 0x22, + 0x0b, 0x31, 0xf4, 0x49, 0x0f, 0x3e, 0xd8, 0x4c, 0xb2, 0x71, 0xa9, 0xc7, 0x64, 0xe3, 0x27, 0xa1, + 0xda, 0x0a, 0x7d, 0xcf, 0xf5, 0x54, 0x0d, 0x4d, 0x96, 0xde, 0xbc, 0x22, 0xda, 0xb0, 0x82, 0xa2, + 0x5b, 0x50, 0xbb, 0x79, 0x2b, 0xe1, 0xa7, 0x3f, 0xc2, 0xbf, 0x5d, 0xd4, 0xa1, 0x8f, 0x32, 0x5a, + 0xd4, 0xf1, 0x12, 0xd6, 0xbc, 0x90, 0x0d, 0xfd, 0x4c, 0x09, 0xca, 0x8c, 0x04, 0xe6, 0x7b, 0x67, + 0xda, 0x31, 0xc6, 0x02, 0x62, 0x7f, 0xad, 0x06, 0xa7, 0xf2, 0x2a, 0xe5, 0xa3, 0x0f, 0x43, 0x3f, + 0xef, 0x63, 0x31, 0x97, 0xb1, 0xe4, 0xf1, 0x98, 0x67, 0x04, 0x45, 0xb7, 0xd8, 0x6f, 0x2c, 0x78, + 0x0a, 0xee, 0xbe, 0xb3, 0x2e, 0x66, 0xc8, 0xf1, 0x70, 0x5f, 0x74, 0x34, 0xf7, 0x45, 0x87, 0x73, + 0xf7, 0x9d, 0x75, 0xb4, 0x03, 0x95, 0x86, 0x97, 0x10, 0x47, 0x38, 0x11, 0x6e, 0x1c, 0x0b, 0x73, + 0xe2, 0x70, 0x2b, 0x8d, 0xfd, 0xc4, 0x9c, 0x21, 0xfa, 0xaa, 0x05, 0xa3, 0xeb, 0xe9, 0x2a, 0x07, + 0x42, 0x78, 0x3a, 0xc7, 0x70, 0x1b, 0x42, 0x9a, 0x11, 0xbf, 0xe0, 0x2c, 0xd3, 0x88, 0xb3, 0xdd, + 0x41, 0x9f, 0xb0, 0x60, 0x60, 0xc3, 0xf3, 0x8d, 0x82, 0xd4, 0xc7, 0xf0, 0x71, 0x2e, 0x32, 0x06, + 0x7a, 0xc7, 0xc1, 0xff, 0xc7, 0x58, 0x72, 0xee, 0xa6, 0xa9, 0xfa, 0x8f, 0xaa, 0xa9, 0x06, 0xee, + 0x93, 0xa6, 0xfa, 0xb4, 0x05, 0x35, 0x35, 0xd2, 0x22, 0x5b, 0xfc, 0x03, 0xc7, 0xf8, 0xc9, 0xb9, + 0xe7, 0x44, 0xfd, 0xc5, 0x9a, 0x39, 0xfa, 0x82, 0x05, 0x83, 0xce, 0x6b, 0xed, 0x88, 0xd4, 0xc9, + 0x76, 0xd8, 0x8a, 0xc5, 0xed, 0xa8, 0x2f, 0x17, 0xdf, 0x99, 0x69, 0xca, 0x64, 0x8e, 0x6c, 0x2f, + 0xb7, 0x62, 0x91, 0x2d, 0xa5, 0x1b, 0xb0, 0xd9, 0x05, 0x7b, 0xaf, 0x04, 0x13, 0x07, 0x50, 0x40, + 0xcf, 0xc3, 0x50, 0x18, 0x35, 0x9c, 0xc0, 0x7b, 0xcd, 0x2c, 0x5b, 0xa2, 0xac, 0xac, 0x65, 0x03, + 0x86, 0x53, 0x98, 0x66, 0x3e, 0x7b, 0xe9, 0x80, 0x7c, 0xf6, 0x73, 0xd0, 0x17, 0x91, 0x56, 0x98, + 0xdd, 0x2c, 0xb0, 0x4c, 0x05, 0x06, 0x41, 0x8f, 0x42, 0xd9, 0x69, 0x79, 0x22, 0x10, 0x4d, 0xed, + 0x81, 0xa6, 0x57, 0x16, 0x30, 0x6d, 0x4f, 0x95, 0xd7, 0xa8, 0xdc, 0x93, 0xf2, 0x1a, 0x54, 0x0d, + 0x88, 0xb3, 0x8b, 0x7e, 0xad, 0x06, 0xd2, 0x67, 0x0a, 0xf6, 0x1b, 0x65, 0x78, 0x74, 0xdf, 0xf9, + 0xa2, 0xe3, 0xf0, 0xac, 0x7d, 0xe2, 0xf0, 0xe4, 0xf0, 0x94, 0x0e, 0x1a, 0x9e, 0x72, 0x97, 0xe1, + 0xf9, 0x04, 0x5d, 0x06, 0xb2, 0xdc, 0x4b, 0x31, 0xf7, 0x5b, 0x76, 0xab, 0x1e, 0x23, 0x56, 0x80, + 0x84, 0x62, 0xcd, 0x97, 0xee, 0x01, 0x52, 0xb9, 0xdc, 0x95, 0x22, 0xd4, 0x40, 0xd7, 0x92, 0x2b, + 0x7c, 0xee, 0x77, 0x4b, 0x10, 0xb7, 0x7f, 0xbb, 0x0f, 0x1e, 0xef, 0x41, 0x7a, 0x9b, 0xb3, 0xd8, + 0xea, 0x71, 0x16, 0xff, 0x80, 0x7f, 0xa6, 0x4f, 0xe5, 0x7e, 0x26, 0x5c, 0xfc, 0x67, 0xda, 0xff, + 0x0b, 0xa1, 0xa7, 0xa0, 0xea, 0x05, 0x31, 0x71, 0xdb, 0x11, 0x8f, 0x49, 0x36, 0xd2, 0x98, 0x16, + 0x44, 0x3b, 0x56, 0x18, 0x74, 0x4f, 0xe7, 0x3a, 0x74, 0xf9, 0x0f, 0x14, 0x94, 0xbb, 0x6b, 0x66, + 0x44, 0x71, 0x93, 0x62, 0x76, 0x9a, 0x4a, 0x00, 0xce, 0xc6, 0xfe, 0x5b, 0x16, 0x9c, 0xe9, 0xae, + 0x62, 0xd1, 0x33, 0x30, 0xb8, 0x1e, 0x39, 0x81, 0xbb, 0xc9, 0x6e, 0x36, 0x96, 0x53, 0x87, 0xbd, + 0xaf, 0x6e, 0xc6, 0x26, 0x0e, 0x9a, 0x85, 0x31, 0x1e, 0xb9, 0x61, 0x60, 0xc8, 0xcc, 0xdf, 0xdb, + 0x7b, 0x13, 0x63, 0x6b, 0x59, 0x20, 0xee, 0xc4, 0xb7, 0xbf, 0x5f, 0xce, 0xef, 0x16, 0x37, 0xc5, + 0x0e, 0x33, 0x9b, 0xc5, 0x5c, 0x2d, 0xf5, 0x20, 0x71, 0xcb, 0xf7, 0x5a, 0xe2, 0xf6, 0x75, 0x93, + 0xb8, 0x68, 0x0e, 0x4e, 0x18, 0x57, 0x4f, 0xf1, 0x6c, 0x6e, 0x1e, 0x96, 0xac, 0x4a, 0xb1, 0xac, + 0x64, 0xe0, 0xb8, 0xe3, 0x89, 0x07, 0x7c, 0xea, 0xfd, 0x5a, 0x09, 0x1e, 0xe9, 0x6a, 0xfd, 0xde, + 0x23, 0x8d, 0x62, 0x7e, 0xfe, 0xbe, 0x7b, 0xf3, 0xf9, 0xcd, 0x8f, 0x52, 0x39, 0xe8, 0xa3, 0xd8, + 0x7f, 0x5c, 0xea, 0xba, 0x10, 0xe8, 0x4e, 0xe8, 0x87, 0x76, 0x94, 0x5e, 0x80, 0x61, 0xa7, 0xd5, + 0xe2, 0x78, 0x2c, 0x8a, 0x36, 0x53, 0xfa, 0x69, 0xda, 0x04, 0xe2, 0x34, 0x6e, 0x4f, 0x36, 0xcd, + 0x9f, 0x58, 0x50, 0xc3, 0x64, 0x83, 0x4b, 0x23, 0x74, 0x53, 0x0c, 0x91, 0x55, 0x44, 0x9d, 0x5b, + 0x3a, 0xb0, 0xb1, 0xc7, 0xea, 0xbf, 0xe6, 0x0d, 0x76, 0xe7, 0x55, 0x64, 0xa5, 0x43, 0x5d, 0x45, + 0xa6, 0x2e, 0xa3, 0x2a, 0x77, 0xbf, 0x8c, 0xca, 0xfe, 0xee, 0x00, 0x7d, 0xbd, 0x56, 0x38, 0x1b, + 0x91, 0x7a, 0x4c, 0xbf, 0x6f, 0x3b, 0xf2, 0xc5, 0x24, 0x51, 0xdf, 0xf7, 0x1a, 0x5e, 0xc4, 0xb4, + 0x3d, 0x75, 0x40, 0x56, 0x3a, 0x54, 0xe1, 0x9b, 0xf2, 0x81, 0x85, 0x6f, 0x5e, 0x80, 0xe1, 0x38, + 0xde, 0x5c, 0x89, 0xbc, 0x6d, 0x27, 0x21, 0x57, 0xc8, 0xae, 0xb0, 0x7d, 0x75, 0x11, 0x88, 0xd5, + 0x4b, 0x1a, 0x88, 0xd3, 0xb8, 0x68, 0x1e, 0xc6, 0x74, 0xf9, 0x19, 0x12, 0x25, 0x2c, 0xe7, 0x82, + 0xcf, 0x04, 0x95, 0xf1, 0xad, 0x0b, 0xd6, 0x08, 0x04, 0xdc, 0xf9, 0x0c, 0x95, 0xa7, 0xa9, 0x46, + 0xda, 0x91, 0xfe, 0xb4, 0x3c, 0x4d, 0xd1, 0xa1, 0x7d, 0xe9, 0x78, 0x02, 0x2d, 0xc1, 0x49, 0x3e, + 0x31, 0xa6, 0x5b, 0x2d, 0xe3, 0x8d, 0x06, 0xd2, 0xf5, 0x45, 0xe7, 0x3b, 0x51, 0x70, 0xde, 0x73, + 0xe8, 0x39, 0x18, 0x54, 0xcd, 0x0b, 0x73, 0xe2, 0x6c, 0x47, 0xf9, 0x96, 0x14, 0x99, 0x85, 0x3a, + 0x36, 0xf1, 0xd0, 0xfb, 0xe1, 0x61, 0xfd, 0x97, 0x27, 0xe6, 0xf1, 0x03, 0xcf, 0x39, 0x51, 0xd9, + 0x4b, 0x5d, 0x7d, 0x34, 0x9f, 0x8b, 0x56, 0xc7, 0xdd, 0x9e, 0x47, 0xeb, 0x70, 0x46, 0x81, 0x2e, + 0x04, 0x09, 0xcb, 0xb2, 0x89, 0xc9, 0x8c, 0x13, 0x93, 0x6b, 0x91, 0x2f, 0xae, 0xd0, 0x56, 0xb7, + 0xe3, 0xce, 0x7b, 0xc9, 0xa5, 0x3c, 0x4c, 0xbc, 0x88, 0xf7, 0xa1, 0x82, 0xa6, 0xa0, 0x46, 0x02, + 0x67, 0xdd, 0x27, 0xcb, 0xb3, 0x0b, 0xac, 0x42, 0x98, 0x71, 0xbe, 0x7a, 0x41, 0x02, 0xb0, 0xc6, + 0x51, 0x71, 0xbf, 0x43, 0x5d, 0x6f, 0x6a, 0x5e, 0x81, 0x53, 0x0d, 0xb7, 0x45, 0x2d, 0x42, 0xcf, + 0x25, 0xd3, 0x2e, 0x0b, 0x73, 0xa4, 0x1f, 0x86, 0x17, 0x7e, 0x55, 0x41, 0xed, 0xf3, 0xb3, 0x2b, + 0x1d, 0x38, 0x38, 0xf7, 0x49, 0x16, 0x0e, 0x1b, 0x85, 0x3b, 0xbb, 0xe3, 0x27, 0x33, 0xe1, 0xb0, + 0xb4, 0x11, 0x73, 0x18, 0xba, 0x0c, 0x88, 0x65, 0x48, 0x5c, 0x4a, 0x92, 0x96, 0x32, 0x41, 0xc7, + 0x4f, 0xa5, 0xeb, 0xfc, 0x5c, 0xec, 0xc0, 0xc0, 0x39, 0x4f, 0x51, 0x8b, 0x26, 0x08, 0x19, 0xf5, + 0xf1, 0x87, 0xd3, 0x16, 0xcd, 0x55, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0xcf, 0x16, 0x0c, 0xab, 0xa5, + 0x7d, 0x0f, 0xd2, 0x89, 0xfc, 0x74, 0x3a, 0xd1, 0xfc, 0xd1, 0x85, 0x23, 0xeb, 0x79, 0x97, 0x98, + 0xf4, 0x6f, 0x0c, 0x02, 0x68, 0x01, 0xaa, 0x74, 0x97, 0xd5, 0x55, 0x77, 0x3d, 0xb0, 0xc2, 0x2b, + 0xaf, 0x22, 0x4f, 0xe5, 0xfe, 0x56, 0xe4, 0x59, 0x85, 0xd3, 0xd2, 0xb2, 0xe0, 0x87, 0x7d, 0x97, + 0xc2, 0x58, 0xc9, 0xc2, 0xea, 0xcc, 0xa3, 0x82, 0xd0, 0xe9, 0x85, 0x3c, 0x24, 0x9c, 0xff, 0x6c, + 0xca, 0xa0, 0x19, 0x38, 0xd0, 0xca, 0x54, 0xcb, 0x7f, 0x71, 0x43, 0x5e, 0x21, 0x94, 0x59, 0xfe, + 0x8b, 0x17, 0x57, 0xb1, 0xc6, 0xc9, 0xd7, 0x01, 0xb5, 0x82, 0x74, 0x00, 0x1c, 0x5a, 0x07, 0x48, + 0x69, 0x34, 0xd8, 0x55, 0x1a, 0xc9, 0x43, 0x85, 0xa1, 0xae, 0x87, 0x0a, 0xef, 0x81, 0x11, 0x2f, + 0xd8, 0x24, 0x91, 0x97, 0x90, 0x3a, 0x5b, 0x0b, 0x4c, 0x52, 0x55, 0xb5, 0x05, 0xb0, 0x90, 0x82, + 0xe2, 0x0c, 0x76, 0x5a, 0x84, 0x8e, 0xf4, 0x20, 0x42, 0xbb, 0x28, 0xae, 0xd1, 0x62, 0x14, 0xd7, + 0x89, 0xa3, 0x2b, 0xae, 0xb1, 0x63, 0x55, 0x5c, 0xa8, 0x10, 0xc5, 0xd5, 0x93, 0x4e, 0x30, 0x76, + 0xa6, 0xa7, 0x0e, 0xd8, 0x99, 0x76, 0xd3, 0x5a, 0xa7, 0xef, 0x5a, 0x6b, 0xe5, 0x2b, 0xa4, 0x87, + 0x8e, 0x5b, 0x21, 0x7d, 0xba, 0x04, 0xa7, 0xb5, 0xc8, 0xa6, 0x0b, 0xc5, 0xdb, 0xa0, 0x42, 0x8b, + 0x5d, 0x58, 0xc7, 0xcf, 0xe8, 0x8c, 0x44, 0x38, 0x9d, 0x53, 0xa7, 0x20, 0xd8, 0xc0, 0x62, 0xf9, + 0x64, 0x24, 0x62, 0xd5, 0xaf, 0xb3, 0xf2, 0x7c, 0x56, 0xb4, 0x63, 0x85, 0x41, 0xa7, 0x22, 0xfd, + 0x2d, 0x72, 0x74, 0xb3, 0x75, 0x15, 0x67, 0x35, 0x08, 0x9b, 0x78, 0xe8, 0x49, 0xce, 0x84, 0xc9, + 0x12, 0x2a, 0xd3, 0x87, 0xc4, 0xad, 0xe0, 0x52, 0x7c, 0x28, 0xa8, 0xec, 0x0e, 0x4b, 0x1c, 0xac, + 0x74, 0x76, 0x87, 0x85, 0xbb, 0x29, 0x0c, 0xfb, 0x7f, 0x5a, 0xf0, 0x48, 0xee, 0x50, 0xdc, 0x03, + 0x3d, 0xbd, 0x93, 0xd6, 0xd3, 0xab, 0x45, 0x6d, 0x62, 0x8c, 0xb7, 0xe8, 0xa2, 0xb3, 0xff, 0xa3, + 0x05, 0x23, 0x1a, 0xff, 0x1e, 0xbc, 0xaa, 0x97, 0x7e, 0xd5, 0xe2, 0xf6, 0x6b, 0xb5, 0x8e, 0x77, + 0xfb, 0xbd, 0x12, 0xa8, 0x5a, 0xa7, 0xd3, 0xae, 0xac, 0x24, 0x7d, 0xc0, 0xa9, 0xf1, 0x2e, 0xf4, + 0xb3, 0x43, 0xef, 0xb8, 0x98, 0x80, 0x9e, 0x34, 0x7f, 0x76, 0x80, 0xae, 0x03, 0x0a, 0xd8, 0xdf, + 0x18, 0x0b, 0x86, 0xac, 0x36, 0x3b, 0x2f, 0x23, 0x59, 0x17, 0x29, 0x78, 0xba, 0x36, 0xbb, 0x68, + 0xc7, 0x0a, 0x83, 0x6a, 0x12, 0xcf, 0x0d, 0x83, 0x59, 0xdf, 0x89, 0xe5, 0x8d, 0xb3, 0x4a, 0x93, + 0x2c, 0x48, 0x00, 0xd6, 0x38, 0xec, 0x3c, 0xdc, 0x8b, 0x5b, 0xbe, 0xb3, 0x6b, 0xec, 0xca, 0x8d, + 0x5a, 0x14, 0x0a, 0x84, 0x4d, 0x3c, 0xbb, 0x09, 0xe3, 0xe9, 0x97, 0x98, 0x23, 0x1b, 0x2c, 0x18, + 0xb5, 0xa7, 0xe1, 0x9c, 0x82, 0x9a, 0xc3, 0x9e, 0x5a, 0x6c, 0x3b, 0x42, 0x26, 0xe8, 0x90, 0x4c, + 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x47, 0x16, 0x9c, 0xcc, 0x19, 0xb4, 0x02, 0x53, 0x1c, 0x13, 0x2d, + 0x6d, 0xf2, 0x6c, 0x80, 0x1f, 0x83, 0x81, 0x3a, 0xd9, 0x70, 0x64, 0xb8, 0xa3, 0x21, 0x3d, 0xe7, + 0x78, 0x33, 0x96, 0x70, 0xfb, 0xb7, 0x4a, 0x30, 0x9a, 0xee, 0x6b, 0xcc, 0xd2, 0x86, 0xf8, 0x30, + 0x79, 0xb1, 0x1b, 0x6e, 0x93, 0x68, 0x97, 0xbe, 0xb9, 0x95, 0x49, 0x1b, 0xea, 0xc0, 0xc0, 0x39, + 0x4f, 0xb1, 0x4a, 0xc7, 0x75, 0x35, 0xda, 0x72, 0x46, 0x5e, 0x2f, 0x72, 0x46, 0xea, 0x8f, 0x69, + 0x86, 0x46, 0x28, 0x96, 0xd8, 0xe4, 0x4f, 0x6d, 0x11, 0x16, 0x87, 0x3d, 0xd3, 0xf6, 0xfc, 0xc4, + 0x0b, 0xc4, 0x2b, 0x8b, 0xb9, 0xaa, 0x6c, 0x91, 0xa5, 0x4e, 0x14, 0x9c, 0xf7, 0x9c, 0xfd, 0xbd, + 0x3e, 0x50, 0x29, 0xd5, 0x2c, 0x74, 0xad, 0xa0, 0xc0, 0xbf, 0xc3, 0x26, 0x9f, 0xa9, 0xb9, 0xd5, + 0xb7, 0x5f, 0x2c, 0x09, 0x77, 0xe5, 0x98, 0xfe, 0x5c, 0x35, 0x60, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, + 0xda, 0x13, 0xdf, 0xdb, 0x26, 0xfc, 0xa1, 0xfe, 0x74, 0x4f, 0x16, 0x25, 0x00, 0x6b, 0x1c, 0xda, + 0x93, 0xba, 0xb7, 0xb1, 0x21, 0xfc, 0x12, 0xaa, 0x27, 0x74, 0x74, 0x30, 0x83, 0xf0, 0x5a, 0xf8, + 0xe1, 0x96, 0xb0, 0xbf, 0x8d, 0x5a, 0xf8, 0xe1, 0x16, 0x66, 0x10, 0xfa, 0x95, 0x82, 0x30, 0x6a, + 0x3a, 0xbe, 0xf7, 0x1a, 0xa9, 0x2b, 0x2e, 0xc2, 0xee, 0x56, 0x5f, 0xe9, 0x6a, 0x27, 0x0a, 0xce, + 0x7b, 0x8e, 0x4e, 0xe8, 0x56, 0x44, 0xea, 0x9e, 0x9b, 0x98, 0xd4, 0x20, 0x3d, 0xa1, 0x57, 0x3a, + 0x30, 0x70, 0xce, 0x53, 0x68, 0x1a, 0x46, 0x65, 0x4a, 0xbc, 0x2c, 0x78, 0x34, 0x98, 0x2e, 0xb0, + 0x82, 0xd3, 0x60, 0x9c, 0xc5, 0xa7, 0x42, 0xb2, 0x29, 0x6a, 0xa2, 0x31, 0x33, 0xdd, 0x10, 0x92, + 0xb2, 0x56, 0x1a, 0x56, 0x18, 0xf6, 0xc7, 0xcb, 0x54, 0xa9, 0x77, 0x29, 0x3d, 0x78, 0xcf, 0x02, + 0x4d, 0xd3, 0x33, 0xb2, 0xaf, 0x87, 0x19, 0xf9, 0x2c, 0x0c, 0xdd, 0x8c, 0xc3, 0x40, 0x05, 0x71, + 0x56, 0xba, 0x06, 0x71, 0x1a, 0x58, 0xf9, 0x41, 0x9c, 0xfd, 0x45, 0x05, 0x71, 0x0e, 0xdc, 0x65, + 0x10, 0xe7, 0x1f, 0x54, 0x40, 0xdd, 0x2b, 0x74, 0x95, 0x24, 0xb7, 0xc2, 0x68, 0xcb, 0x0b, 0x1a, + 0xac, 0x94, 0xc0, 0x57, 0x2d, 0x18, 0xe2, 0xeb, 0x65, 0xd1, 0x4c, 0xc2, 0xdb, 0x28, 0xe8, 0xc2, + 0x9a, 0x14, 0xb3, 0xc9, 0x35, 0x83, 0x51, 0xe6, 0xce, 0x61, 0x13, 0x84, 0x53, 0x3d, 0x42, 0x1f, + 0x01, 0x90, 0x4e, 0xdc, 0x0d, 0x29, 0x81, 0x17, 0x8a, 0xe9, 0x1f, 0x26, 0x1b, 0xda, 0xa4, 0x5e, + 0x53, 0x4c, 0xb0, 0xc1, 0x10, 0x7d, 0x5a, 0x27, 0x28, 0xf2, 0x6c, 0x8f, 0x0f, 0x1d, 0xcb, 0xd8, + 0xf4, 0x92, 0x9e, 0x88, 0x61, 0xc0, 0x0b, 0x1a, 0x74, 0x9e, 0x88, 0x60, 0xb7, 0xb7, 0xe7, 0x95, + 0xe1, 0x58, 0x0c, 0x9d, 0xfa, 0x8c, 0xe3, 0x3b, 0x81, 0x4b, 0xa2, 0x05, 0x8e, 0xae, 0x35, 0xa8, + 0x68, 0xc0, 0x92, 0x50, 0xc7, 0x8d, 0x4c, 0x95, 0x5e, 0x6e, 0x64, 0x3a, 0xf3, 0x5e, 0x18, 0xeb, + 0xf8, 0x98, 0x87, 0xca, 0x46, 0xbc, 0xfb, 0x44, 0x46, 0xfb, 0xb7, 0xfb, 0xb5, 0xd2, 0xba, 0x1a, + 0xd6, 0xf9, 0x05, 0x3f, 0x91, 0xfe, 0xa2, 0xc2, 0x64, 0x2e, 0x70, 0x8a, 0x28, 0x35, 0x63, 0x34, + 0x62, 0x93, 0x25, 0x9d, 0xa3, 0x2d, 0x27, 0x22, 0xc1, 0x71, 0xcf, 0xd1, 0x15, 0xc5, 0x04, 0x1b, + 0x0c, 0xd1, 0x66, 0x2a, 0x1d, 0xe9, 0xe2, 0xd1, 0xd3, 0x91, 0x58, 0x81, 0xb2, 0xbc, 0x7b, 0x30, + 0xbe, 0x60, 0xc1, 0x48, 0x90, 0x9a, 0xb9, 0xc5, 0x44, 0x20, 0xe7, 0xaf, 0x0a, 0x7e, 0x2d, 0x5d, + 0xba, 0x0d, 0x67, 0xf8, 0xe7, 0xa9, 0xb4, 0xca, 0x21, 0x55, 0x9a, 0xbe, 0x60, 0xac, 0xbf, 0xdb, + 0x05, 0x63, 0x28, 0x50, 0x37, 0x2c, 0x0e, 0x14, 0x7e, 0xc3, 0x22, 0xe4, 0xdc, 0xae, 0x78, 0x03, + 0x6a, 0x6e, 0x44, 0x9c, 0xe4, 0x2e, 0x2f, 0xdb, 0x63, 0xb1, 0x1d, 0xb3, 0x92, 0x00, 0xd6, 0xb4, + 0xec, 0xff, 0xd3, 0x07, 0x27, 0xe4, 0x88, 0xc8, 0xec, 0x05, 0xaa, 0x1f, 0x39, 0x5f, 0x6d, 0x2b, + 0x2b, 0xfd, 0x78, 0x49, 0x02, 0xb0, 0xc6, 0xa1, 0xf6, 0x58, 0x3b, 0x26, 0xcb, 0x2d, 0x12, 0x2c, + 0x7a, 0xeb, 0xb1, 0x38, 0x8c, 0x55, 0x0b, 0xe5, 0x9a, 0x06, 0x61, 0x13, 0x8f, 0xda, 0xf6, 0x8e, + 0x61, 0xb4, 0x1a, 0xb6, 0xbd, 0x34, 0x54, 0x25, 0x1c, 0xfd, 0x72, 0x6e, 0x2d, 0xe4, 0x62, 0x72, + 0xfe, 0x3a, 0x92, 0x36, 0x0e, 0x79, 0x3f, 0xeb, 0xdf, 0xb7, 0xe0, 0x34, 0x6f, 0x95, 0x23, 0x79, + 0xad, 0x55, 0x77, 0x12, 0x12, 0x17, 0x73, 0x87, 0x42, 0x4e, 0xff, 0xb4, 0x7b, 0x39, 0x8f, 0x2d, + 0xce, 0xef, 0x0d, 0x7a, 0xdd, 0x82, 0xd1, 0xad, 0x54, 0xb9, 0x18, 0xa9, 0x3a, 0x8e, 0x5a, 0xc9, + 0x21, 0x45, 0x54, 0x2f, 0xb5, 0x74, 0x7b, 0x8c, 0xb3, 0xdc, 0xed, 0xff, 0x61, 0x81, 0x29, 0x46, + 0xef, 0x7d, 0x95, 0x99, 0xc3, 0x9b, 0x82, 0xd2, 0xba, 0xac, 0x74, 0xb5, 0x2e, 0x1f, 0x85, 0x72, + 0xdb, 0xab, 0x8b, 0xfd, 0x85, 0x3e, 0x22, 0x5e, 0x98, 0xc3, 0xb4, 0xdd, 0xfe, 0x97, 0x15, 0xed, + 0x06, 0x11, 0x29, 0x75, 0x3f, 0x14, 0xaf, 0xbd, 0xa1, 0xea, 0xd4, 0xf1, 0x37, 0xbf, 0xda, 0x51, + 0xa7, 0xee, 0xa7, 0x0e, 0x9f, 0x31, 0xc9, 0x07, 0xa8, 0x5b, 0x99, 0xba, 0x81, 0x03, 0xd2, 0x25, + 0x6f, 0x42, 0x95, 0x6e, 0xc1, 0x98, 0x3f, 0xb3, 0x9a, 0xea, 0x54, 0xf5, 0x92, 0x68, 0xbf, 0xb3, + 0x37, 0xf1, 0xae, 0xc3, 0x77, 0x4b, 0x3e, 0x8d, 0x15, 0x7d, 0x14, 0x43, 0x8d, 0xfe, 0x66, 0x99, + 0x9d, 0x62, 0x73, 0x77, 0x4d, 0xc9, 0x4c, 0x09, 0x28, 0x24, 0x6d, 0x54, 0xf3, 0x41, 0x01, 0xd4, + 0xd8, 0x55, 0xd6, 0x8c, 0x29, 0xdf, 0x03, 0xae, 0xa8, 0xfc, 0x4a, 0x09, 0xb8, 0xb3, 0x37, 0xf1, + 0xc2, 0xe1, 0x99, 0xaa, 0xc7, 0xb1, 0x66, 0x61, 0xff, 0x75, 0x9f, 0x9e, 0xbb, 0xa2, 0x3c, 0xe1, + 0x0f, 0xc5, 0xdc, 0x7d, 0x3e, 0x33, 0x77, 0xcf, 0x75, 0xcc, 0xdd, 0x11, 0x7d, 0xe5, 0x72, 0x6a, + 0x36, 0xde, 0x6b, 0x43, 0xe0, 0x60, 0x7f, 0x03, 0xb3, 0x80, 0x5e, 0x6d, 0x7b, 0x11, 0x89, 0x57, + 0xa2, 0x76, 0xe0, 0x05, 0x0d, 0x36, 0x1d, 0xab, 0xa6, 0x05, 0x94, 0x02, 0xe3, 0x2c, 0x3e, 0xdd, + 0xd4, 0xd3, 0x6f, 0x7e, 0xc3, 0xd9, 0xe6, 0xb3, 0xca, 0xa8, 0xd8, 0xb6, 0x2a, 0xda, 0xb1, 0xc2, + 0x40, 0x9b, 0x70, 0x56, 0x12, 0x98, 0x23, 0x3e, 0x11, 0x77, 0x26, 0x6f, 0x78, 0x51, 0x93, 0x07, + 0x88, 0xf3, 0xc8, 0x84, 0xb7, 0x09, 0x0a, 0x67, 0xf1, 0x3e, 0xb8, 0x78, 0x5f, 0x4a, 0xf6, 0xd7, + 0xd9, 0x79, 0xbd, 0x91, 0xbc, 0x4e, 0x67, 0x9f, 0xcf, 0x6e, 0x29, 0xe7, 0x85, 0xe5, 0xd4, 0xec, + 0xe3, 0x57, 0x93, 0x73, 0x18, 0xba, 0x05, 0x03, 0xeb, 0xfc, 0xbe, 0xcd, 0x62, 0x6a, 0xfb, 0x8b, + 0xcb, 0x3b, 0xd9, 0x4d, 0x46, 0xf2, 0x26, 0xcf, 0x3b, 0xfa, 0x27, 0x96, 0xdc, 0xec, 0x6f, 0x55, + 0x60, 0x34, 0x73, 0x8f, 0x75, 0xaa, 0xa4, 0x6f, 0xe9, 0xc0, 0x92, 0xbe, 0x1f, 0x04, 0xa8, 0x93, + 0x96, 0x1f, 0xee, 0x32, 0xc3, 0xaf, 0xef, 0xd0, 0x86, 0x9f, 0xda, 0x2b, 0xcc, 0x29, 0x2a, 0xd8, + 0xa0, 0x28, 0xaa, 0xe9, 0xf1, 0x0a, 0xc1, 0x99, 0x6a, 0x7a, 0xc6, 0x0d, 0x20, 0xfd, 0xf7, 0xf6, + 0x06, 0x10, 0x0f, 0x46, 0x79, 0x17, 0x55, 0x8a, 0xf8, 0x5d, 0x64, 0x82, 0xb3, 0x24, 0x9b, 0xb9, + 0x34, 0x19, 0x9c, 0xa5, 0x7b, 0x3f, 0xaf, 0xa9, 0x47, 0xef, 0x80, 0x9a, 0xfc, 0xce, 0xf1, 0x78, + 0x4d, 0x97, 0xd9, 0x90, 0xd3, 0x80, 0x5d, 0x1f, 0x2f, 0x7e, 0x76, 0x54, 0xbb, 0x80, 0xfb, 0x55, + 0xed, 0xc2, 0xfe, 0x7c, 0x89, 0xee, 0x18, 0x78, 0xbf, 0x54, 0xe1, 0xa6, 0x27, 0xa0, 0xdf, 0x69, + 0x27, 0x9b, 0x61, 0xc7, 0x8d, 0x9d, 0xd3, 0xac, 0x15, 0x0b, 0x28, 0x5a, 0x84, 0xbe, 0xba, 0x2e, + 0xc6, 0x73, 0x98, 0xef, 0xa9, 0x9d, 0xaf, 0x4e, 0x42, 0x30, 0xa3, 0x82, 0xce, 0x42, 0x5f, 0xe2, + 0x34, 0x64, 0x5e, 0x20, 0xcb, 0x05, 0x5f, 0x73, 0x1a, 0x31, 0x66, 0xad, 0xa6, 0xa1, 0xd0, 0x77, + 0x80, 0xa1, 0xf0, 0x02, 0x0c, 0xc7, 0x5e, 0x23, 0x70, 0x92, 0x76, 0x44, 0x8c, 0xf3, 0x49, 0x1d, + 0x9d, 0x62, 0x02, 0x71, 0x1a, 0xd7, 0xfe, 0x9d, 0x21, 0x38, 0xb5, 0x3a, 0xbb, 0x24, 0x4b, 0xcc, + 0x1f, 0x5b, 0x6a, 0x5f, 0x1e, 0x8f, 0x7b, 0x97, 0xda, 0xd7, 0x85, 0xbb, 0x6f, 0xa4, 0xf6, 0xf9, + 0x46, 0x6a, 0x5f, 0x3a, 0xcf, 0xaa, 0x5c, 0x44, 0x9e, 0x55, 0x5e, 0x0f, 0x7a, 0xc9, 0xb3, 0x3a, + 0xb6, 0x5c, 0xbf, 0x7d, 0x3b, 0x74, 0xa8, 0x5c, 0x3f, 0x95, 0x08, 0x59, 0x48, 0x06, 0x4c, 0x97, + 0x4f, 0x95, 0x9b, 0x08, 0xa9, 0x92, 0xd0, 0x78, 0x76, 0x97, 0x10, 0xf5, 0x2f, 0x17, 0xdf, 0x81, + 0x1e, 0x92, 0xd0, 0x44, 0x82, 0x99, 0x99, 0xf8, 0x38, 0x50, 0x44, 0xe2, 0x63, 0x5e, 0x77, 0x0e, + 0x4c, 0x7c, 0x7c, 0x01, 0x86, 0x5d, 0x3f, 0x0c, 0xc8, 0x4a, 0x14, 0x26, 0xa1, 0x1b, 0xca, 0x3b, + 0x03, 0xf5, 0x95, 0x37, 0x26, 0x10, 0xa7, 0x71, 0xbb, 0x65, 0x4d, 0xd6, 0x8e, 0x9a, 0x35, 0x09, + 0xf7, 0x29, 0x6b, 0xf2, 0x17, 0x74, 0x7e, 0xff, 0x20, 0xfb, 0x22, 0x1f, 0x2c, 0xfe, 0x8b, 0xf4, + 0x74, 0x29, 0xe0, 0x1b, 0xfc, 0xca, 0x4c, 0x6a, 0x82, 0xcf, 0x86, 0x4d, 0x6a, 0xf8, 0x0d, 0xb1, + 0x21, 0x79, 0xe5, 0x18, 0x26, 0xec, 0x8d, 0x55, 0xcd, 0x46, 0x5d, 0xa3, 0xa9, 0x9b, 0x70, 0xba, + 0x23, 0x47, 0xa9, 0x3f, 0xf0, 0xe5, 0x12, 0xfc, 0xc8, 0x81, 0x5d, 0x40, 0xb7, 0x00, 0x12, 0xa7, + 0x21, 0x26, 0xaa, 0x38, 0x9a, 0x39, 0x62, 0x08, 0xe9, 0x9a, 0xa4, 0xc7, 0x0b, 0xe7, 0xa8, 0xbf, + 0xec, 0xd0, 0x43, 0xfe, 0x66, 0x91, 0xa3, 0xa1, 0xdf, 0x51, 0x5f, 0x14, 0x87, 0x3e, 0xc1, 0x0c, + 0x42, 0xd5, 0x7f, 0x44, 0x1a, 0xfa, 0xbe, 0x79, 0xf5, 0xf9, 0x30, 0x6b, 0xc5, 0x02, 0x8a, 0x9e, + 0x83, 0x41, 0xc7, 0xf7, 0x79, 0x7a, 0x12, 0x89, 0xc5, 0x5d, 0x54, 0xba, 0xd0, 0xa1, 0x06, 0x61, + 0x13, 0xcf, 0xfe, 0xcb, 0x12, 0x4c, 0x1c, 0x20, 0x53, 0x3a, 0xd2, 0x52, 0x2b, 0x3d, 0xa7, 0xa5, + 0x8a, 0x94, 0x8d, 0xfe, 0x2e, 0x29, 0x1b, 0xcf, 0xc1, 0x60, 0x42, 0x9c, 0xa6, 0x08, 0x3a, 0x13, + 0x3e, 0x07, 0x7d, 0xd6, 0xac, 0x41, 0xd8, 0xc4, 0xa3, 0x52, 0x6c, 0xc4, 0x71, 0x5d, 0x12, 0xc7, + 0x32, 0x27, 0x43, 0xf8, 0x6d, 0x0b, 0x4b, 0xf8, 0x60, 0xee, 0xf0, 0xe9, 0x14, 0x0b, 0x9c, 0x61, + 0x99, 0x1d, 0xf0, 0x5a, 0x8f, 0x03, 0xfe, 0xb5, 0x12, 0x3c, 0xba, 0xaf, 0x76, 0xeb, 0x39, 0x5d, + 0xa6, 0x1d, 0x93, 0x28, 0x3b, 0x71, 0xae, 0xc5, 0x24, 0xc2, 0x0c, 0xc2, 0x47, 0xa9, 0xd5, 0x32, + 0xee, 0xf3, 0x2f, 0x3a, 0x77, 0x8c, 0x8f, 0x52, 0x8a, 0x05, 0xce, 0xb0, 0xbc, 0xdb, 0x69, 0xf9, + 0xad, 0x3e, 0x78, 0xbc, 0x07, 0x1b, 0xa0, 0xc0, 0x1c, 0xbb, 0x74, 0x3e, 0x68, 0xf9, 0x3e, 0xe5, + 0x83, 0xde, 0xdd, 0x70, 0xbd, 0x99, 0x46, 0xda, 0x53, 0x2e, 0xdf, 0xd7, 0x4b, 0x70, 0xa6, 0xbb, + 0xc1, 0x82, 0xde, 0x0d, 0xa3, 0x91, 0x0a, 0xb2, 0x33, 0x53, 0x49, 0x4f, 0x72, 0xcf, 0x4e, 0x0a, + 0x84, 0xb3, 0xb8, 0x68, 0x12, 0xa0, 0xe5, 0x24, 0x9b, 0xf1, 0x85, 0x1d, 0x2f, 0x4e, 0x44, 0x41, + 0xa9, 0x11, 0x7e, 0x96, 0x28, 0x5b, 0xb1, 0x81, 0x41, 0xd9, 0xb1, 0x7f, 0x73, 0xe1, 0xd5, 0x30, + 0xe1, 0x0f, 0xf1, 0xcd, 0xd6, 0x49, 0x79, 0xfd, 0x8e, 0x01, 0xc2, 0x59, 0x5c, 0xca, 0x8e, 0x9d, + 0x56, 0xf3, 0x8e, 0xf2, 0x5d, 0x18, 0x63, 0xb7, 0xa8, 0x5a, 0xb1, 0x81, 0x91, 0x4d, 0x92, 0xad, + 0x1c, 0x9c, 0x24, 0x6b, 0xff, 0x8b, 0x12, 0x3c, 0xd2, 0xd5, 0xe0, 0xed, 0x4d, 0x4c, 0x3d, 0x78, + 0x89, 0xad, 0x77, 0xb9, 0xc2, 0x0e, 0x97, 0x10, 0xf9, 0x27, 0x5d, 0x66, 0x9a, 0x48, 0x88, 0xbc, + 0xfb, 0x3a, 0x0f, 0x0f, 0xde, 0x78, 0x76, 0xe4, 0x40, 0xf6, 0x1d, 0x22, 0x07, 0x32, 0xf3, 0x31, + 0x2a, 0x3d, 0x6a, 0x87, 0x3f, 0xeb, 0xeb, 0x3a, 0xbc, 0x74, 0x83, 0xdc, 0x93, 0xdf, 0x7c, 0x0e, + 0x4e, 0x78, 0x01, 0xbb, 0x8a, 0x6d, 0xb5, 0xbd, 0x2e, 0x6a, 0x0c, 0xf1, 0x42, 0x9a, 0x2a, 0xd1, + 0x62, 0x21, 0x03, 0xc7, 0x1d, 0x4f, 0x3c, 0x80, 0x39, 0xa9, 0x77, 0x37, 0xa4, 0x87, 0x94, 0xdc, + 0xcb, 0x70, 0x5a, 0x0e, 0xc5, 0xa6, 0x13, 0x91, 0xba, 0x50, 0xb6, 0xb1, 0x48, 0xad, 0x79, 0x84, + 0xa7, 0xe7, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0xed, 0x57, 0x61, 0xcb, 0x73, 0xc5, 0x56, 0x50, + 0xdf, 0x7e, 0x45, 0x1b, 0x31, 0x87, 0x69, 0x7d, 0x51, 0xbb, 0x37, 0xfa, 0xe2, 0x83, 0x50, 0x53, + 0xe3, 0xcd, 0xb3, 0x04, 0xd4, 0x24, 0xef, 0xc8, 0x12, 0x50, 0x33, 0xdc, 0xc0, 0x3a, 0xe8, 0x7a, + 0xd6, 0x9f, 0x80, 0x21, 0xe5, 0xfd, 0xea, 0xf5, 0x0e, 0x32, 0xfb, 0xcf, 0xfb, 0x61, 0x38, 0x55, + 0x57, 0x34, 0xe5, 0xf6, 0xb6, 0x0e, 0x74, 0x7b, 0xb3, 0x04, 0x91, 0x76, 0x20, 0x2f, 0x28, 0x34, + 0x12, 0x44, 0xda, 0x01, 0xc1, 0x1c, 0x46, 0x37, 0x1d, 0xf5, 0x68, 0x17, 0xb7, 0x03, 0x11, 0xf1, + 0xaa, 0x36, 0x1d, 0x73, 0xac, 0x15, 0x0b, 0x28, 0xfa, 0x98, 0x05, 0x43, 0x31, 0x3b, 0xbd, 0xe1, + 0x87, 0x06, 0x62, 0x92, 0x5f, 0x3e, 0x7a, 0xd9, 0x54, 0x55, 0x43, 0x97, 0x45, 0x48, 0x99, 0x2d, + 0x38, 0xc5, 0x11, 0x7d, 0xd2, 0x82, 0x9a, 0xba, 0x47, 0x49, 0xdc, 0x36, 0xba, 0x5a, 0x6c, 0xd9, + 0x56, 0xee, 0x6d, 0x56, 0x07, 0x61, 0xaa, 0x7e, 0x26, 0xd6, 0x8c, 0x51, 0xac, 0x3c, 0xfa, 0x03, + 0xc7, 0xe3, 0xd1, 0x87, 0x1c, 0x6f, 0xfe, 0x3b, 0xa0, 0xd6, 0x74, 0x02, 0x6f, 0x83, 0xc4, 0x09, + 0x77, 0xb2, 0xcb, 0x6a, 0xd2, 0xb2, 0x11, 0x6b, 0x38, 0x35, 0x00, 0x62, 0xf6, 0x62, 0x89, 0xe1, + 0x15, 0x67, 0x06, 0xc0, 0xaa, 0x6e, 0xc6, 0x26, 0x8e, 0xe9, 0xc2, 0x87, 0xfb, 0xea, 0xc2, 0x1f, + 0x3c, 0xc0, 0x85, 0xbf, 0x0a, 0xa7, 0x9d, 0x76, 0x12, 0x5e, 0x22, 0x8e, 0x3f, 0xcd, 0xaf, 0x0e, + 0x16, 0x57, 0xe1, 0x0f, 0x31, 0xb7, 0x90, 0x8a, 0xe9, 0x58, 0x25, 0xfe, 0x46, 0x07, 0x12, 0xce, + 0x7f, 0xd6, 0xfe, 0xa7, 0x16, 0x9c, 0xce, 0x9d, 0x0a, 0x0f, 0x6e, 0x34, 0xad, 0xfd, 0xa5, 0x0a, + 0x9c, 0xcc, 0xa9, 0x3a, 0x8c, 0x76, 0xcd, 0x45, 0x62, 0x15, 0x11, 0x98, 0x92, 0x8e, 0xb3, 0x90, + 0xdf, 0x26, 0x67, 0x65, 0x1c, 0xee, 0x54, 0x4e, 0x9f, 0x8c, 0x95, 0xef, 0xed, 0xc9, 0x98, 0x31, + 0xd7, 0xfb, 0xee, 0xeb, 0x5c, 0xaf, 0x1c, 0x30, 0xd7, 0xbf, 0x61, 0xc1, 0x78, 0xb3, 0xcb, 0x55, + 0x17, 0xc2, 0xc7, 0x7c, 0xfd, 0x78, 0x2e, 0xd2, 0x98, 0x39, 0x7b, 0x7b, 0x6f, 0xa2, 0xeb, 0x0d, + 0x23, 0xb8, 0x6b, 0xaf, 0xec, 0xef, 0x95, 0x81, 0x95, 0xbc, 0x66, 0x95, 0x25, 0x77, 0xd1, 0x47, + 0xcd, 0xe2, 0xe5, 0x56, 0x51, 0x85, 0xb6, 0x39, 0x71, 0x55, 0xfc, 0x9c, 0x8f, 0x60, 0x5e, 0x2d, + 0xf4, 0xac, 0x24, 0x2c, 0xf5, 0x20, 0x09, 0x7d, 0x59, 0x25, 0xbe, 0x5c, 0x7c, 0x95, 0xf8, 0x5a, + 0xb6, 0x42, 0xfc, 0xfe, 0x9f, 0xb8, 0xef, 0x81, 0xfc, 0xc4, 0xbf, 0x62, 0x71, 0xc1, 0x93, 0xf9, + 0x0a, 0xda, 0xdc, 0xb0, 0xf6, 0x31, 0x37, 0x9e, 0x82, 0x6a, 0x2c, 0x24, 0xb3, 0x30, 0x4b, 0x74, + 0x50, 0x84, 0x68, 0xc7, 0x0a, 0x83, 0x5d, 0x23, 0xed, 0xfb, 0xe1, 0xad, 0x0b, 0xcd, 0x56, 0xb2, + 0x2b, 0x0c, 0x14, 0x7d, 0x8d, 0xb4, 0x82, 0x60, 0x03, 0xcb, 0xfe, 0x7b, 0x25, 0x3e, 0x03, 0x45, + 0x64, 0xcd, 0xf3, 0x99, 0x8b, 0x3f, 0x7b, 0x0f, 0x4a, 0xf9, 0x30, 0x80, 0x1b, 0x36, 0x5b, 0xd4, + 0x78, 0x5d, 0x0b, 0xc5, 0xf1, 0xdf, 0xa5, 0xa3, 0x1a, 0xa2, 0x92, 0x9e, 0x7e, 0x0d, 0xdd, 0x86, + 0x0d, 0x7e, 0x29, 0x59, 0x5a, 0x3e, 0x50, 0x96, 0xa6, 0xc4, 0x4a, 0xdf, 0xfe, 0x62, 0xc5, 0xfe, + 0x4b, 0x0b, 0x52, 0x66, 0x16, 0x6a, 0x41, 0x85, 0x76, 0x77, 0x57, 0xac, 0xd0, 0xe5, 0xe2, 0x6c, + 0x3a, 0x2a, 0x1a, 0xc5, 0xb4, 0x67, 0x3f, 0x31, 0x67, 0x84, 0x7c, 0x11, 0x80, 0xc3, 0x47, 0xf5, + 0x6a, 0x71, 0x0c, 0x2f, 0x85, 0xe1, 0x16, 0x3f, 0xc3, 0xd6, 0xc1, 0x3c, 0xf6, 0xf3, 0x30, 0xd6, + 0xd1, 0x29, 0x76, 0xc7, 0x5f, 0x48, 0xb5, 0x4f, 0x66, 0xba, 0xb2, 0x7c, 0x64, 0xcc, 0x61, 0xf6, + 0xd7, 0x2d, 0x38, 0x91, 0x25, 0x8f, 0xde, 0xb0, 0x60, 0x2c, 0xce, 0xd2, 0x3b, 0xae, 0xb1, 0x53, + 0x41, 0xb4, 0x1d, 0x20, 0xdc, 0xd9, 0x09, 0xfb, 0xaf, 0xc5, 0xe4, 0xbf, 0xe1, 0x05, 0xf5, 0xf0, + 0x96, 0x32, 0x4c, 0xac, 0xae, 0x86, 0x09, 0x5d, 0x8f, 0xee, 0x26, 0xa9, 0xb7, 0xfd, 0x8e, 0xec, + 0xe6, 0x55, 0xd1, 0x8e, 0x15, 0x06, 0x4b, 0xe6, 0x6c, 0x8b, 0x6b, 0x24, 0x32, 0x93, 0x72, 0x4e, + 0xb4, 0x63, 0x85, 0x81, 0x9e, 0x85, 0x21, 0xe3, 0x25, 0xe5, 0xbc, 0x64, 0x56, 0xbe, 0xa1, 0x32, + 0x63, 0x9c, 0xc2, 0x42, 0x93, 0x00, 0xca, 0xc8, 0x91, 0x2a, 0x92, 0x79, 0xbb, 0x94, 0x24, 0x8a, + 0xb1, 0x81, 0xc1, 0x52, 0xa7, 0xfd, 0x76, 0xcc, 0x8e, 0x73, 0xfa, 0x75, 0x69, 0xe3, 0x59, 0xd1, + 0x86, 0x15, 0x94, 0x4a, 0x93, 0xa6, 0x13, 0xb4, 0x1d, 0x9f, 0x8e, 0x90, 0xd8, 0xbf, 0xaa, 0x65, + 0xb8, 0xa4, 0x20, 0xd8, 0xc0, 0xa2, 0x6f, 0x9c, 0x78, 0x4d, 0xf2, 0x52, 0x18, 0xc8, 0xe0, 0x47, + 0x7d, 0xc2, 0x27, 0xda, 0xb1, 0xc2, 0xb0, 0xff, 0xc2, 0x82, 0x51, 0x5d, 0xb3, 0x81, 0xdf, 0xe6, + 0x6f, 0x6e, 0xb7, 0xad, 0x03, 0xb7, 0xdb, 0xe9, 0x0c, 0xf5, 0x52, 0x4f, 0x19, 0xea, 0x66, 0xf2, + 0x78, 0x79, 0xdf, 0xe4, 0xf1, 0x1f, 0xd5, 0x37, 0x45, 0xf3, 0x2c, 0xf3, 0xc1, 0xbc, 0x5b, 0xa2, + 0x91, 0x0d, 0xfd, 0xae, 0xa3, 0x6a, 0x1b, 0x0d, 0xf1, 0x0d, 0xc9, 0xec, 0x34, 0x43, 0x12, 0x10, + 0x7b, 0x19, 0x6a, 0xea, 0xa0, 0x4b, 0xee, 0x7e, 0xad, 0xfc, 0xdd, 0x6f, 0x4f, 0x49, 0xac, 0x33, + 0xeb, 0xdf, 0xfc, 0xfe, 0x63, 0x6f, 0xf9, 0xa3, 0xef, 0x3f, 0xf6, 0x96, 0xef, 0x7e, 0xff, 0xb1, + 0xb7, 0x7c, 0xec, 0xf6, 0x63, 0xd6, 0x37, 0x6f, 0x3f, 0x66, 0xfd, 0xd1, 0xed, 0xc7, 0xac, 0xef, + 0xde, 0x7e, 0xcc, 0xfa, 0xde, 0xed, 0xc7, 0xac, 0x2f, 0xfc, 0xd7, 0xc7, 0xde, 0xf2, 0x52, 0x6e, + 0xf4, 0x2b, 0xfd, 0xf1, 0xb4, 0x5b, 0x9f, 0xda, 0x3e, 0xcf, 0x02, 0x30, 0xe9, 0xf2, 0x9a, 0x32, + 0xe6, 0xd4, 0x94, 0x5c, 0x5e, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x57, 0x97, 0x8d, 0x5b, + 0xec, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -7369,6 +7378,14 @@ func (m *ApplicationSourceHelm) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + 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]) @@ -8656,6 +8673,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 +8758,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 { @@ -13160,6 +13198,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 @@ -14189,6 +14235,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]) @@ -15689,6 +15738,7 @@ func (m *ApplicationSourceHelm) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 2 return n } @@ -16161,6 +16211,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 +16235,7 @@ func (m *ClusterGenerator) Size() (n int) { n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } + n += 2 return n } @@ -17845,6 +17899,7 @@ func (m *ResourceStatus) Size() (n int) { n += 2 n += 2 n += 1 + sovGenerated(uint64(m.SyncWave)) + n += 2 return n } @@ -18235,6 +18290,7 @@ func (m *SyncOperation) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 1 + sovGenerated(uint64(m.SelfHealAttemptsCount)) return n } @@ -19035,6 +19091,7 @@ 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) + `,`, `}`, }, "") return s @@ -19390,6 +19447,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 +19471,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 @@ -20705,6 +20765,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 @@ -20959,6 +21020,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 @@ -27732,6 +27794,26 @@ 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) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -31707,6 +31789,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 +32084,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:]) @@ -47185,6 +47339,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:]) @@ -50611,6 +50785,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:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index 0b79d47202cb9..5911cfd171e3d 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; } @@ -515,6 +515,9 @@ 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; } // ApplicationSourceJsonnet holds options specific to applications of type Jsonnet @@ -838,6 +841,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 +860,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 @@ -1956,6 +1968,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 @@ -2256,6 +2270,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. diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 1b2533532bc0e..5221381ed80da 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -2997,6 +2997,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: "", + }, + }, }, }, }, diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 0112ac161782e..998b1fbf1dfb6 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" @@ -395,6 +397,8 @@ 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"` } // HelmParameter is a parameter that's passed to helm template during manifest generation @@ -476,7 +480,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.KubeVersion == "" && len(h.APIVersions) == 0 && h.Namespace == "" } // KustomizeImage represents a Kustomize image definition in the format [old_image_name=]: @@ -999,6 +1003,12 @@ type ApplicationDestination struct { isServerInferred 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 var ( @@ -1037,6 +1047,16 @@ type ApplicationStatus struct { ControllerNamespace string `json:"controllerNamespace,omitempty" protobuf:"bytes,13,opt,name=controllerNamespace"` } +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 +} + // 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 +1073,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 +1191,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" @@ -1806,16 +1828,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 +1958,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 +2058,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 +2408,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 +2421,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 +2438,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 +2462,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 +2586,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 +2676,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 +2820,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 @@ -3074,6 +3127,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 +3153,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 +3252,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 { + return nil, fmt.Errorf("Unable to get K8s RAW REST config: %w", err) + } + err = SetK8SConfigDefaults(config) if err != nil { - panic(fmt.Sprintf("Unable to apply K8s REST config defaults: %v", err)) + return nil, fmt.Errorf("Unable to apply K8s REST config defaults: %w", err) } - return config + return config, nil } // UnmarshalToUnstructured unmarshals a resource representation in JSON to unstructured data @@ -3279,3 +3360,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..484467a8f7a6f 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -320,7 +320,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 +339,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 +366,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 +454,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 +816,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 +1792,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 +1821,7 @@ func TestSyncWindows_Active(t *testing.T) { currentTime time.Time matchingIndex int expectedLength int + isErr bool }{ { name: "MatchFirst", @@ -1912,11 +1929,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 +1975,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 +2004,7 @@ func TestSyncWindows_InactiveAllows(t *testing.T) { currentTime time.Time matchingIndex int expectedLength int + isErr bool }{ { name: "MatchFirst", @@ -2085,11 +2130,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 +2268,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 +2280,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 +2295,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 +2309,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 +2323,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 +2337,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 +2352,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 +2367,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 +2381,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 +2395,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 +2409,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 +2423,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 +2438,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 +2453,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 +2468,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 +2482,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 +2496,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 +2510,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 +2524,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 +2541,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 +2558,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 +2573,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 +2588,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 +2603,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 +2670,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 +2697,7 @@ func TestSyncWindow_Active(t *testing.T) { syncWindow SyncWindow currentTime time.Time expectedResult bool + isErr bool }{ { name: "Allow-active", @@ -2639,11 +2747,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 +2896,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 +2982,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 +3003,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 +3026,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 +3062,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 +3086,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 +3105,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 +3127,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) @@ -3959,3 +4117,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..dc80bffd77243 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 } @@ -1522,6 +1545,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 +1870,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 @@ -3068,6 +3128,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 +3190,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 } @@ -3945,6 +4020,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 +4139,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 } 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/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..1e4083d989769 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,6 +2363,13 @@ func (m *UpdateRevisionForPathsRequest) GetNoRevisionCache() bool { return false } +func (m *UpdateRevisionForPathsRequest) GetInstallationID() string { + if m != nil { + return m.InstallationID + } + return "" +} + type UpdateRevisionForPathsResponse struct { Changes bool `protobuf:"varint,1,opt,name=changes,proto3" json:"changes,omitempty"` Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` @@ -2449,153 +2475,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 +3262,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 +5304,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 +5619,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 +6486,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 +7408,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 +12808,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/askpass/server.go b/reposerver/askpass/server.go index 2eb9f89869776..b6a1bbfc48de2 100644 --- a/reposerver/askpass/server.go +++ b/reposerver/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/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/repository.go b/reposerver/repository/repository.go index e387a5bf93380..cf3a22e0a8bbe 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) } @@ -1188,6 +1191,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie } passCredentials = appHelm.PassCredentials templateOpts.SkipCrds = appHelm.SkipCrds + templateOpts.SkipTests = appHelm.SkipTests } if templateOpts.Name == "" { templateOpts.Name = q.AppName @@ -1376,8 +1380,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 +1411,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 +1460,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 +1503,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 +1977,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 +1991,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 +2038,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 +2047,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) } @@ -2864,7 +2900,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..2f45007d0e884 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,6 +285,7 @@ message UpdateRevisionForPathsRequest { repeated string paths = 13; bool noRevisionCache = 14; + string installationID = 15; } message UpdateRevisionForPathsResponse { diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 0c11553e5d7f4..57256dce7468e 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) @@ -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}$") @@ -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") }) } @@ -1849,6 +1847,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 +1861,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 +1876,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 +1891,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 +1906,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 +1921,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 +1954,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 +1963,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 +1993,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 +2024,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 +2055,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 +2077,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 +2108,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 +2125,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 +2389,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 +2404,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 +2870,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 +2952,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 +2971,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)) } @@ -3078,6 +3092,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() 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/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/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/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..2e7f9ab669e9d 100644 --- a/server/account/account_test.go +++ b/server/account/account_test.go @@ -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 f5eecd9d8c6ad..de961c82ea5f7 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -112,6 +112,7 @@ func NewServer( settingsMgr *settings.SettingsManager, projInformer cache.SharedIndexInformer, enabledNamespaces []string, + enableK8sEvent []string, ) (application.ApplicationServiceServer, AppResourceTreeFn) { if appBroadcaster == nil { appBroadcaster = &broadcasterHandler{} @@ -133,7 +134,7 @@ func NewServer( kubectl: kubectl, enf: enf, projectLock: projectLock, - auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"), + auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), settingsMgr: settingsMgr, projInformer: projInformer, enabledNamespaces: enabledNamespaces, @@ -509,26 +510,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) @@ -550,7 +557,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) } @@ -629,22 +636,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()) @@ -676,7 +684,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) } @@ -923,8 +931,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 @@ -1281,7 +1289,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 } @@ -1361,7 +1373,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) } @@ -1373,9 +1385,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 } @@ -1412,7 +1424,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) } @@ -1886,7 +1898,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") } @@ -2168,7 +2184,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) } @@ -2603,10 +2619,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 78381bb49dc05..a030131f679a9 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -69,6 +69,8 @@ const ( fakeRepoURL = "https://git.com/repo.git" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + func fakeRepo() *appsv1.Repository { return &appsv1.Repository{ Repo: fakeRepoURL, @@ -129,14 +131,16 @@ 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 { +func newTestAppServerWithEnforcerConfigure(t *testing.T, f func(*rbac.Enforcer), additionalConfig map[string]string, objects ...runtime.Object) *Server { + t.Helper() kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, @@ -306,20 +310,23 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, settingsMgr, projInformer, []string{}, + testEnableEventList, ) return server.(*Server) } // 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 { +func newTestAppServerWithEnforcerConfigureWithBenchmark(b *testing.B, f func(*rbac.Enforcer), objects ...runtime.Object) *Server { + b.Helper() kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, @@ -486,6 +493,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(f func(*rbac.Enforcer), settingsMgr, projInformer, []string{}, + testEnableEventList, ) return server.(*Server) } @@ -788,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 @@ -1092,6 +1100,7 @@ func TestNoAppEnumeration(t *testing.T) { // 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) @@ -1103,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) @@ -1149,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 @@ -1330,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{}) @@ -2003,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) }) } @@ -2224,6 +2235,7 @@ func TestMaxPodLogsRender(t *testing.T) { // 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) @@ -2265,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...) @@ -2275,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) @@ -2714,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) }) 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/websocket_test.go b/server/application/websocket_test.go index 0d048a1727d1b..eb1f760685e78 100644 --- a/server/application/websocket_test.go +++ b/server/application/websocket_test.go @@ -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() diff --git a/server/applicationset/applicationset.go b/server/applicationset/applicationset.go index 4d08e6f7d560a..b5288c71c1509 100644 --- a/server/applicationset/applicationset.go +++ b/server/applicationset/applicationset.go @@ -88,6 +88,7 @@ func NewServer( scmRootCAPath string, allowedScmProviders []string, enableScmProviders bool, + enableK8sEvent []string, ) applicationset.ApplicationSetServiceServer { s := &Server{ ns: namespace, @@ -103,7 +104,7 @@ func NewServer( projLister: projLister, settings: settings, projectLock: projectLock, - auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"), + auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), enabledNamespaces: enabledNamespaces, GitSubmoduleEnabled: gitSubmoduleEnabled, EnableNewGitFileGlobbing: enableNewGitFileGlobbing, @@ -264,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) @@ -299,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 4e2492a31a838..4385d2ef57ef2 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -22,6 +22,7 @@ import ( apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/assets" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/argo-cd/v2/util/errors" @@ -34,6 +35,8 @@ const ( fakeRepoURL = "https://git.com/repo.git" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + func fakeRepo() *appsv1.Repository { return &appsv1.Repository{ Repo: fakeRepoURL, @@ -162,6 +165,7 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace "", []string{}, true, + testEnableEventList, ) return server.(*Server) } @@ -186,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 diff --git a/server/badge/badge_test.go b/server/badge/badge_test.go index 8e1d8819165bf..9c996ca4873d8 100644 --- a/server/badge/badge_test.go +++ b/server/badge/badge_test.go @@ -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() diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index c92600448ed75..8ffa787437f62 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -146,7 +146,12 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* return nil, err } c := q.Cluster - serverVersion, err := s.kubectl.GetServerVersion(c.RESTConfig()) + clusterRESTConfig, err := c.RESTConfig() + if err != nil { + return nil, err + } + + serverVersion, err := s.kubectl.GetServerVersion(clusterRESTConfig) if err != nil { return nil, err } @@ -313,9 +318,13 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (* } q.Cluster = c } + clusterRESTConfig, err := q.Cluster.RESTConfig() + if err != nil { + return nil, 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 } @@ -406,7 +415,10 @@ 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, err + } if restCfg.BearerToken == "" { return nil, status.Errorf(codes.InvalidArgument, "Cluster '%s' does not use bearer token authentication", server) } @@ -428,8 +440,12 @@ func (s *Server) RotateAuth(ctx context.Context, q *cluster.ClusterQuery) (*clus clust.Config.CertData = nil clust.Config.BearerToken = string(newSecret.Data["token"]) + clusterRESTConfig, err := clust.RESTConfig() + if err != nil { + return nil, 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 } diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 567de3a661901..e54ecbfb6e92a 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( @@ -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, `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 @@ -471,8 +575,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 +583,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/") }) } 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..f57d88c46a807 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -27,7 +27,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -46,7 +46,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -61,7 +61,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -76,7 +76,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -91,7 +91,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -107,7 +107,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -123,7 +123,7 @@ 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) + r, err := http.NewRequest(http.MethodGet, "http://null", nil) if err != nil { t.Fatalf("error initializing request: %s", err) } @@ -150,7 +150,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 +162,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 +227,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 +254,7 @@ func TestCallExtension(t *testing.T) { userMock *mocks.UserGetter manager *extension.Manager } + defaultServerNamespace := "control-plane-ns" defaultProjectName := "project-name" setup := func() *fixture { @@ -260,7 +267,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 +368,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) } @@ -444,6 +453,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 +804,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/project/project.go b/server/project/project.go index 3406c87315259..62487b268a705 100644 --- a/server/project/project.go +++ b/server/project/project.go @@ -58,9 +58,9 @@ type Server struct { // NewServer returns a new instance of the Project service func NewServer(ns string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface, enf *rbac.Enforcer, projectLock sync.KeyLock, sessionMgr *session.SessionManager, policyEnf *rbacpolicy.RBACPolicyEnforcer, - projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB, + projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB, enableK8sEvent []string, ) *Server { - auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server") + auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server", enableK8sEvent) return &Server{ enf: enf, policyEnf: policyEnf, appclientset: appclientset, kubeclientset: kubeclientset, ns: ns, projectLock: projectLock, auditLogger: auditLogger, sessionMgr: sessionMgr, projInformer: projInformer, settingsMgr: settingsMgr, db: db, @@ -525,7 +525,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 a03f472696f5a..cd5a8de5fee53 100644 --- a/server/project/project_test.go +++ b/server/project/project_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/pkg/sync" @@ -37,6 +38,8 @@ import ( const testNamespace = "default" +var testEnableEventList []string = argo.DefaultEnableEventList() + func TestProjectServer(t *testing.T) { kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ ObjectMeta: v1.ObjectMeta{ @@ -91,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) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) err := projectServer.NormalizeProjs() require.NoError(t, err) @@ -105,7 +108,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = nil @@ -119,7 +122,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = nil @@ -133,7 +136,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.ClusterResourceWhitelist = []metav1.GroupKind{{}} @@ -147,7 +150,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{{}} @@ -166,7 +169,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] @@ -183,7 +186,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] @@ -202,7 +205,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} @@ -219,7 +222,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} @@ -239,7 +242,7 @@ func TestProjectServer(t *testing.T) { Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := proj.DeepCopy() updatedProj.Spec.SourceRepos = []string{"https://github.com/argoproj/*"} @@ -266,7 +269,7 @@ func TestProjectServer(t *testing.T) { argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := proj.DeepCopy() updatedProj.Spec.Destinations = []v1alpha1.ApplicationDestination{ @@ -281,7 +284,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestDeleteProjectSuccessful", func(t *testing.T) { argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) @@ -294,7 +297,7 @@ func TestProjectServer(t *testing.T) { Spec: v1alpha1.AppProjectSpec{}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: defaultProj.Name}) statusCode, _ := status.FromError(err) @@ -308,7 +311,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) @@ -335,7 +338,7 @@ func TestProjectServer(t *testing.T) { projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName}} argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test") }) @@ -345,7 +348,7 @@ func TestProjectServer(t *testing.T) { projectWithRole := existingProj.DeepCopy() projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName, Groups: []string{"my-group"}}} argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1}) require.NoError(t, err) }) @@ -359,7 +362,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 100}) require.NoError(t, err) claims, _, err := sessionMgr.Parse(tokenResponse.Token) @@ -380,7 +383,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) require.NoError(t, err) claims, _, err := sessionMgr.Parse(tokenResponse.Token) @@ -401,7 +404,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) require.NoError(t, err) @@ -430,7 +433,7 @@ func TestProjectServer(t *testing.T) { token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test") }) @@ -443,7 +446,7 @@ func TestProjectServer(t *testing.T) { token := v1alpha1.ProjectRole{Name: tokenName, Groups: []string{"my-group"}, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) require.NoError(t, err) }) @@ -459,7 +462,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) require.NoError(t, err) projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -483,7 +486,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt, ID: id}, {IssuedAt: secondIssuedAt, ID: secondId}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: secondIssuedAt, Id: id}) require.NoError(t, err) projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -502,7 +505,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projWithToken.Name, Role: tokenName}) require.NoError(t, err) projWithTwoTokens, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -516,7 +519,7 @@ p, role:admin, projects, update, *, allow`) wildSourceRepo := "*" proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, wildSourceRepo) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: proj} updatedProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -535,7 +538,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -557,7 +560,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + 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) expectedErr := fmt.Sprintf("rpc error: code = AlreadyExists desc = policy '%s' already exists for role '%s'", policy, roleName) @@ -577,10 +580,10 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + 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) { @@ -596,10 +599,10 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + 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) { @@ -615,10 +618,10 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + 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) { @@ -633,10 +636,10 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + 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) { @@ -652,7 +655,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} updateProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -667,7 +670,7 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + 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: projectWithSyncWindows.Name}) require.NoError(t, err) assert.Len(t, res.Windows, 1) @@ -680,9 +683,9 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + 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) }) @@ -698,7 +701,7 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: projectWithSyncWindows.Name}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, get, test") }) diff --git a/server/rbacpolicy/rbacpolicy.go b/server/rbacpolicy/rbacpolicy.go index 0be623ae7819f..800dcd43c064a 100644 --- a/server/rbacpolicy/rbacpolicy.go +++ b/server/rbacpolicy/rbacpolicy.go @@ -46,8 +46,11 @@ var ( ResourceApplicationSets, ResourceRepositories, ResourceCertificates, + ResourceAccounts, + ResourceGPGKeys, ResourceLogs, ResourceExec, + ResourceExtensions, } Actions = []string{ ActionGet, @@ -56,6 +59,8 @@ var ( ActionDelete, ActionSync, ActionOverride, + ActionAction, + ActionInvoke, } ) diff --git a/server/repository/repository.go b/server/repository/repository.go index 2e25f87ce19d1..001818490f37e 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -128,6 +128,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 @@ -146,30 +147,7 @@ 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 - } - // 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, - } - - item.ConnectionState = s.getConnectionState(ctx, item.Repo, item.Project, q.ForceRefresh) - - return &item, nil + return repo, nil } // ListRepositories returns a list of all configured repositories and the state of their connections diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index 72354633048dc..64c215c70f668 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -369,6 +369,68 @@ func TestRepositoryServer(t *testing.T) { assert.Equal(t, "rpc error: code = NotFound desc = repo 'https://test' not found", err.Error()) }) + 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"}}, 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) + repo, err := s.Get(context.TODO(), &repository.RepoQuery{ + Repo: url, + }) + require.NoError(t, err) + assert.Equal(t, "https://test", repo.Repo) + 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) + 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) + 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) { repoServerClient := mocks.RepoServerServiceClient{} repoServerClient.On("TestRepository", mock.Anything, mock.Anything).Return(&apiclient.TestRepositoryResponse{}, nil) diff --git a/server/server.go b/server/server.go index 8ad9e451a898d..6625461dfab03 100644 --- a/server/server.go +++ b/server/server.go @@ -229,6 +229,7 @@ type ArgoCDServerOpts struct { ApplicationNamespaces []string EnableProxyExtension bool WebhookParallelism int + EnableK8sEvent []string } type ApplicationSetOpts struct { @@ -327,7 +328,7 @@ 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) a := &ArgoCDServer{ ArgoCDServerOpts: opts, @@ -560,7 +561,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 } @@ -705,7 +712,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) @@ -885,7 +892,9 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { projectLock, a.settingsMgr, a.projInformer, - a.ApplicationNamespaces) + a.ApplicationNamespaces, + a.EnableK8sEvent, + ) applicationSetService := applicationset.NewServer( a.db, @@ -907,9 +916,10 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { a.ScmRootCAPath, a.AllowedScmProviders, a.EnableScmProviders, + a.EnableK8sEvent, ) - projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db) + 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) accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf) @@ -1283,7 +1293,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..1f715d00d4e91 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -51,6 +51,7 @@ type FakeArgoCDServer struct { } func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { + t.Helper() cm := test.NewFakeConfigMap() secret := test.NewFakeSecret() kubeclientset := fake.NewSimpleClientset(cm, secret) @@ -477,6 +478,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 +544,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 +1358,7 @@ func TestCacheControlHeaders(t *testing.T) { name: "file exists", filename: "exists.html", createFile: true, - expectedStatus: 200, + expectedStatus: http.StatusOK, expectedCacheControlHeaders: nil, }, { @@ -1369,7 +1372,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 +1535,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 +1546,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.proto b/server/settings/settings.proto index 4b2396d5a22a4..943aea41cd207 100644 --- a/server/settings/settings.proto +++ b/server/settings/settings.proto @@ -43,6 +43,7 @@ message Settings { string controllerNamespace = 23; bool appsInAnyNamespaceEnabled = 24; bool impersonationEnabled = 25; + string installationID = 26; } message GoogleAnalyticsConfig { diff --git a/test/container/Dockerfile b/test/container/Dockerfile index 8d1cfcc98e818..cb01e50e0952b 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.8.0@sha256:bd00c03095f7586432805dbf7989be10361d27987f93de904b1fc003949a4794 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.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 as golang FROM docker.io/library/registry:2.8@sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90 as registry -FROM docker.io/bitnami/kubectl:1.31@sha256:27e5f500a2de2ba249a159c4af0b075500ad8a1afaa59ba1edf09bf83c656fd4 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/e2e/app_deletion_test.go b/test/e2e/app_deletion_test.go index 9158dddffa06a..bb8704a0ca07c 100644 --- a/test/e2e/app_deletion_test.go +++ b/test/e2e/app_deletion_test.go @@ -58,7 +58,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..9eb28233c4f8f 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") }) } @@ -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") @@ -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) } } diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index 67e1b4b03397c..8a5896fbdc560 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") }) } @@ -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") @@ -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) } } @@ -2246,8 +2244,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). @@ -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/applicationset_test.go b/test/e2e/applicationset_test.go index 5df36d591b1d9..1e1447ddbcb4d 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" @@ -2103,6 +2107,7 @@ func TestSimpleGitFilesPreserveResourcesOnDeletionGoTemplate(t *testing.T) { } 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,6 +2297,7 @@ 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 { @@ -2669,6 +2675,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 +2711,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..66c5e8e0787e4 100644 --- a/test/e2e/cluster_test.go +++ b/test/e2e/cluster_test.go @@ -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") }) } diff --git a/test/e2e/custom_tool_test.go b/test/e2e/custom_tool_test.go index d5433977afa3f..955a37f975c1b 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" @@ -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 @@ -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,6 +88,65 @@ 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(1 * time.Second) + 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(1 * time.Second) + 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) @@ -168,6 +238,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 diff --git a/test/e2e/deployment_test.go b/test/e2e/deployment_test.go index 083a2a60d9b3d..ccc3af69a0c87 100644 --- a/test/e2e/deployment_test.go +++ b/test/e2e/deployment_test.go @@ -259,6 +259,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{ diff --git a/test/e2e/fixture/account/context.go b/test/e2e/fixture/account/context.go index 507ca0bd07f2c..6007392da6022 100644 --- a/test/e2e/fixture/account/context.go +++ b/test/e2e/fixture/account/context.go @@ -18,6 +18,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. 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..2628b573ec5db 100644 --- a/test/e2e/fixture/app/actions.go +++ b/test/e2e/fixture/app/actions.go @@ -269,6 +269,9 @@ func (a *Actions) prepareCreateAppArgs(args []string) []string { if a.context.helmSkipCrds { args = append(args, "--helm-skip-crds") } + if a.context.helmSkipTests { + args = append(args, "--helm-skip-tests") + } return args } @@ -382,6 +385,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()) @@ -469,6 +480,11 @@ func (a *Actions) SetTrackingMethod(trackingMethod string) *Actions { return a } +func (a *Actions) SetInstallationID(installationID string) *Actions { + fixture.SetInstallationID(installationID) + return a +} + func (a *Actions) SetTrackingLabel(trackingLabel string) *Actions { fixture.SetTrackingLabel(trackingLabel) return a diff --git a/test/e2e/fixture/app/consequences.go b/test/e2e/fixture/app/consequences.go index 9ee99fec6ca6d..ff64dee0de4b8 100644 --- a/test/e2e/fixture/app/consequences.go +++ b/test/e2e/fixture/app/consequences.go @@ -42,6 +42,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..7755a733c8898 100644 --- a/test/e2e/fixture/app/context.go +++ b/test/e2e/fixture/app/context.go @@ -43,6 +43,7 @@ type Context struct { replace bool helmPassCredentials bool helmSkipCrds bool + helmSkipTests bool trackingMethod v1alpha1.TrackingMethod sources []v1alpha1.ApplicationSource } @@ -52,17 +53,20 @@ 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 { + 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) @@ -357,11 +361,21 @@ func (c *Context) HelmSkipCrds() *Context { return c } +func (c *Context) HelmSkipTests() *Context { + c.helmSkipTests = true + return c +} + func (c *Context) SetTrackingMethod(trackingMethod string) *Context { fixture.SetTrackingMethod(trackingMethod) return c } +func (c *Context) SetInstallationID(installationID string) *Context { + fixture.SetTrackingMethod(installationID) + return c +} + func (c *Context) GetTrackingMethod() v1alpha1.TrackingMethod { return c.trackingMethod } diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index daa2474ea01d5..83894f732504b 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -21,6 +21,7 @@ type Context struct { } func Given(t *testing.T) *Context { + t.Helper() utils.EnsureCleanState(t) return &Context{t: t} } diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index 1ff0fbbfd6137..bd8d035018d71 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -106,6 +106,7 @@ 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() @@ -366,6 +367,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..9024b2d828a23 100644 --- a/test/e2e/fixture/cluster/context.go +++ b/test/e2e/fixture/cluster/context.go @@ -22,11 +22,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) diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go index 24d0e4ce74d71..f2f366c201240 100644 --- a/test/e2e/fixture/fixture.go +++ b/test/e2e/fixture/fixture.go @@ -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" @@ -403,6 +406,13 @@ func SetResourceOverrides(overrides map[string]v1alpha1.ResourceOverride) { SetResourceOverridesSplitKeys(overrides) } +func SetInstallationID(installationID string) { + updateSettingConfigMap(func(cm *corev1.ConfigMap) error { + cm.Data["installationID"] = installationID + return nil + }) +} + func SetTrackingMethod(trackingMethod string) { updateSettingConfigMap(func(cm *corev1.ConfigMap) error { cm.Data["application.resourceTrackingMethod"] = trackingMethod @@ -564,6 +574,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) @@ -974,6 +985,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 +997,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 +1006,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 +1034,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..622032441ee75 100644 --- a/test/e2e/fixture/notification/actions.go +++ b/test/e2e/fixture/notification/actions.go @@ -12,6 +12,8 @@ import ( // using the Then() type Actions struct { context *Context + + healthy bool } func (a *Actions) SetParamInNotificationConfigMap(key, value string) *Actions { @@ -25,3 +27,12 @@ func (a *Actions) Then() *Consequences { 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/context.go b/test/e2e/fixture/project/context.go index e637acbba8cf4..55f8d36199112 100644 --- a/test/e2e/fixture/project/context.go +++ b/test/e2e/fixture/project/context.go @@ -20,11 +20,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) diff --git a/test/e2e/fixture/repos/context.go b/test/e2e/fixture/repos/context.go index 28064e721c5f4..4df9c1e4bb594 100644 --- a/test/e2e/fixture/repos/context.go +++ b/test/e2e/fixture/repos/context.go @@ -20,6 +20,7 @@ type Context struct { } func Given(t *testing.T, sameState bool) *Context { + t.Helper() if !sameState { fixture.EnsureCleanState(t) } diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index 9a95829c33c50..d0b3443000a95 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 diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go index 5fe2248051737..f69fc18defcc5 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(). 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..62cd7fef56e04 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:768e5c6f5cb6db0794eec98dc7a967f40631746c32232b78a3105fb946f3ab83 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..01b2b472d5acb 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, @@ -163,22 +164,19 @@ func TestAddProjectDestination(t *testing.T) { "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) @@ -249,8 +247,7 @@ func TestRemoveProjectDestination(t *testing.T) { "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 { @@ -419,8 +416,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) @@ -466,8 +462,7 @@ 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 { @@ -612,10 +607,217 @@ func TestGetVirtualProjectMatch(t *testing.T) { // 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") + 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") + 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{}) + if err != nil { + t.Fatalf("Unable to create project %v", err) + } + + // 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", + ) + if err != nil { + t.Fatalf("Unable to add project destination service account %v", err) + } + + // 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", + ) + if err != nil { + t.Fatalf("Unable to add project destination service account %v", err) + } + + // 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", + ) + if err != nil { + t.Fatalf("Unable to add project destination service account %v", err) + } + + // 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/scoped_repository_test.go b/test/e2e/scoped_repository_test.go index d1da08b0a434d..8578f2fa90932 100644 --- a/test/e2e/scoped_repository_test.go +++ b/test/e2e/scoped_repository_test.go @@ -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") }) } @@ -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") }) } @@ -170,7 +170,7 @@ 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") }) } 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_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/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..d1bed0ae1a323 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.3@sha256:d56c3e08fe5b27729ee3834854ae8f7015af48fd651cd25d1e3bcf3c19830174 AS go RUN go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest diff --git a/ui-test/Dockerfile b/ui-test/Dockerfile index 134c3cffead31..7469b94b002ea 100644 --- a/ui-test/Dockerfile +++ b/ui-test/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/node:22.9.0@sha256:fa4b468061bd2630567be979ad4899c19dae312262186d501ce73e0875ed4d12 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 041e43ac3160a..6da353a8a874d 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.23", + "@types/selenium-webdriver": "^4.1.27", "assert": "^2.1.0", - "chromedriver": "^128.0.3", - "selenium-webdriver": "^4.21.0" + "chromedriver": "^130.0.4", + "selenium-webdriver": "^4.26.0" }, "devDependencies": { - "@types/mocha": "^10.0.8", - "@types/node": "^22.5.5", + "@types/mocha": "^10.0.9", + "@types/node": "^22.8.7", "dotenv": "^16.4.5", "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.6.3", "yarn": "^1.22.22" } } diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index 1f6205097d09f..cb9c7694b9356 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -23,6 +23,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@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" resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090" @@ -33,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.8.7": + version "22.8.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.7.tgz#04ab7a073d95b4a6ee899f235d43f3c320a976f4" + integrity sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" -"@types/selenium-webdriver@^4.1.23": - version "4.1.23" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.23.tgz#05a2794927db661f075ab443d5504b679b32f7f7" - integrity sha512-PgreEfCfafYLyTwvJTZvOspCq3JABnS51e+NSFFL5yoiMO7h04lWgLfr10NA7nl/yZbz4m76rBfOOdDfleb7pQ== +"@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" "*" @@ -262,10 +267,10 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" -chromedriver@^128.0.3: - version "128.0.3" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-128.0.3.tgz#7c2cd2d160f269e78f40840ee7a043dac3687148" - integrity sha512-Xn/bknOpGlY9tKinwS/hVWeNblSeZvbbJbF8XZ73X1jeWfAFPRXx3fMLdNNz8DqruDbx3cKEJ5wR3mnst6G3iw== +chromedriver@^130.0.4: + version "130.0.4" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-130.0.4.tgz#55225ddfec428e306116507651f5a24fdb299bd6" + integrity sha512-lpR+PWXszij1k4Ig3t338Zvll9HtCTiwoLM7n4pCCswALHxzmgwaaIFBh3rt9+5wRk9D07oFblrazrBxwaYYAQ== dependencies: "@testim/chrome-version" "^1.1.4" axios "^1.7.4" @@ -1267,14 +1272,15 @@ 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.21.0: - version "4.21.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.21.0.tgz#d38aebfc34770421a880afcfdb7bd8fe85ce9174" - integrity sha512-WaEJHZjOWNth1QG5FEpxpREER0qptZBMonFU6GtAqdCNLJVxbtC3E7oS/I/+Q1sf1W032Wg0Ebk+m46lANOXyQ== +selenium-webdriver@^4.26.0: + version "4.26.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.26.0.tgz#23163cdad20388214a4ad17c1f38262a0857c902" + integrity sha512-nA7jMRIPV17mJmAiTDBWN96Sy0Uxrz5CCLb7bLVV6PpL417SyBMPc2Zo/uoREc2EOHlzHwHwAlFtgmSngSY4WQ== dependencies: + "@bazel/runfiles" "^6.3.1" jszip "^3.10.1" tmp "^0.2.3" - ws ">=8.16.0" + ws "^8.18.0" semver@^5.3.0: version "5.7.2" @@ -1477,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.6.3: + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== -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== @@ -1540,10 +1546,10 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@>=8.16.0: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" - integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== y18n@^5.0.5: version "5.0.8" 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/application-deployment-history/application-deployment-history-details.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx new file mode 100644 index 0000000000000..2b25eaead14e4 --- /dev/null +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx @@ -0,0 +1,205 @@ +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 {Repo, Revision} from '../../../shared/components'; +import {services} from '../../../shared/services'; +import {ApplicationParameters} from '../application-parameters/application-parameters'; +import {RevisionMetadataRows} from './revision-metadata-rows'; + +type props = { + app: models.Application; + info: models.RevisionHistory; + index: number; +}; + +export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) => { + const deployments = (app.status.history || []).slice().reverse(); + 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}; + }); + + 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 ( + <> + {info.sources === undefined ? ( + +
    +
    +
    Revision:
    +
    + +
    +
    +
    + + + {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) + )} +
    + ) : ( + info.sources.map((source, i) => ( + + {i > 0 ?
    : null} +
    +
    +
    Repo URL:
    +
    + +
    +
    +
    +
    Revision:
    +
    + +
    +
    +
    + + {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 c24fab22e00eb..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 @@ -1,22 +1,18 @@ -import {DataLoader, DropDownMenu, Duration} from 'argo-ui'; +import {DropDownMenu, Duration} from 'argo-ui'; import {InitiatedBy} from './initiated-by'; import * as moment from 'moment'; import * as React from 'react'; -import {Revision, Timestamp} from '../../../shared/components'; +import {Timestamp} from '../../../shared/components'; import * as models from '../../../shared/models'; -import {services} from '../../../shared/services'; -import {ApplicationParameters} from '../application-parameters/application-parameters'; -import {RevisionMetadataRows} from './revision-metadata-rows'; import './application-deployment-history.scss'; +import {ApplicationDeploymentHistoryDetails} from './application-deployment-history-details'; export const ApplicationDeploymentHistory = ({ app, rollbackApp, - selectedRollbackDeploymentIndex, selectDeployment }: { app: models.Application; - selectedRollbackDeploymentIndex: number; rollbackApp: (info: models.RevisionHistory) => any; selectDeployment: (index: number) => any; }) => { @@ -24,11 +20,9 @@ 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}; }); - const [showParameterDetails, setShowParameterDetails] = React.useState(Boolean); - return (
    {recentDeployments.map((info, index) => ( @@ -43,7 +37,7 @@ export const ApplicationDeploymentHistory = ({
    Time to deploy:
    - {(info.deployStartedAt && ) || 'Unknown'} + {(info.deployStartedAt && ) || 'Unknown'}

    @@ -55,7 +49,7 @@ export const ApplicationDeploymentHistory = ({
    Active for:
    - +
    @@ -78,104 +72,8 @@ export const ApplicationDeploymentHistory = ({
    - {selectedRollbackDeploymentIndex === index ? ( - info.sources === undefined ? ( - -
    -
    -
    Revision:
    -
    - -
    -
    -
    - - - {showParameterDetails && ( - services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    - )} -
    - ) : ( - info.sources.map((source, i) => ( - - {i > 0 ?
    : null} -
    -
    -
    Revision:
    -
    - -
    -
    -
    - - - - {showParameterDetails && ( - services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    - )} - - )) - ) - ) : ( -

    Click to see source details.

    - )} +
    ))} 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 ( ) { super(props); + this.state = { + page: 0, + groupedResources: [], + slidingPanelPage: 0, + filteredGraph: [], + truncateNameOnRight: false, + collapsedNodes: [], + ...this.getExtensionsState() + }; + if (typeof this.props.match.params.appnamespace === 'undefined') { + this.appNamespace = ''; + } else { + this.appNamespace = this.props.match.params.appnamespace; + } + } + + 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 onExtensionsUpdate = () => { + this.setState({...this.state, ...this.getExtensionsState()}); + }; + + private getExtensionsState = () => { const extensions = services.extensions.getAppViewExtensions(); const extensionsMap: {[key: string]: AppViewExtension} = {}; extensions.forEach(ext => { @@ -101,26 +136,8 @@ 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 showOperationState() { return new URLSearchParams(this.props.history.location.search).get('operation') === 'true'; @@ -296,7 +313,7 @@ export class ApplicationDetails extends React.Component -1 && ( this.rollbackApplication(info, application)} selectDeployment={i => this.setRollbackPanelVisible(i)} /> @@ -889,7 +905,7 @@ export class ApplicationDetails extends React.Component} this.setExtensionPanelVisible('')}> {this.selectedExtension !== '' && activeTopBarActionMenuExt?.flyout && ( @@ -920,19 +936,30 @@ 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) }, { 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)) }, { 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.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: , @@ -947,11 +974,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: ( @@ -1171,6 +1207,17 @@ Are you sure you want to disable auto-sync and rollback application '${this.prop private async deleteApplication() { await AppUtils.deleteApplication(this.props.match.params.name, this.appNamespace, this.appContext.apis); } + + private async confirmDeletion(app: appModels.Application, title: string, message: string) { + const confirmed = await this.appContext.apis.popup.confirm(title, message); + if (confirmed) { + if (!app.metadata.annotations) { + app.metadata.annotations = {}; + } + app.metadata.annotations[appModels.AppDeletionConfirmedAnnotation] = new Date().toISOString(); + await services.applications.update(app); + } + } } const ExtensionView = (props: {extension: AppViewExtension; application: models.Application; tree: models.ApplicationTree}) => { diff --git a/ui/src/app/applications/components/application-details/application-resource-filter.tsx b/ui/src/app/applications/components/application-details/application-resource-filter.tsx index a3d99f92488f3..242189ff0a9ef 100644 --- a/ui/src/app/applications/components/application-details/application-resource-filter.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-filter.tsx @@ -145,7 +145,7 @@ export const Filters = (props: FiltersProps) => { {ResourceFilter({ label: 'HEALTH STATUS', prefix: 'health', - options: ['Healthy', 'Progressing', 'Degraded', 'Suspended', 'Missing', 'Unknown'].map(label => ({ + options: ['Progressing', 'Suspended', 'Healthy', 'Degraded', 'Missing', 'Unknown'].map(label => ({ label, count: getOptionCount(label, 'Health'), icon: 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..893172296c4fb 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 @@ -233,11 +233,25 @@ export const ApplicationNodeInfo = (props: { } /> + + services.viewPreferences.updatePreferences({ + appDetails: { + ...pref.appDetails, + enableWordWrap: !pref.appDetails.enableWordWrap + } + }) + } + /> +
    services.applications.patchResource( props.application.metadata.name, @@ -280,7 +294,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..37c22cfed267c 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 @@ -61,7 +61,9 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl title: 'DURATION', value: ( - {time => } + {time => ( + + )} ) } 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..3771d32d3cf1a 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -304,7 +304,7 @@ export const ApplicationParameters = (props: { props.handleCollapse(index, !currentState); }}>
    - +
    Source {index + 1 + ': ' + appSource.repoURL}
    @@ -320,7 +320,7 @@ export const ApplicationParameters = (props: {
    { props.handleCollapse(index, !props.collapsedSources[index]); }} @@ -644,23 +644,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..c5d6ca4050291 100644 --- a/ui/src/app/applications/components/application-parameters/source-panel.tsx +++ b/ui/src/app/applications/components/application-parameters/source-panel.tsx @@ -104,37 +104,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 +157,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'); } @@ -206,12 +206,12 @@ export const SourcePanel = (props: {
    {(repoType === 'git' && ( - +
    (src.repoURL && @@ -247,7 +247,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 +284,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 +304,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 +337,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.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx index 643e24034d54a..ee76418546a4e 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 @@ -112,7 +112,7 @@ 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) && (
    diff --git a/ui/src/app/applications/components/application-summary/application-summary.tsx b/ui/src/app/applications/components/application-summary/application-summary.tsx index 174c66c5dc196..6dbd5081806ae 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -172,7 +172,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { }, !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-source.tsx b/ui/src/app/applications/components/applications-list/applications-source.tsx index 0a5fbe51f37c0..d0fe9d096444a 100644 --- a/ui/src/app/applications/components/applications-list/applications-source.tsx +++ b/ui/src/app/applications/components/applications-list/applications-source.tsx @@ -5,7 +5,7 @@ import {ApplicationSource as ApplicationSourceType} from '../../../shared/models import './applications-source.scss'; export const ApplicationsSource = ({source}: {source: ApplicationSourceType}) => { - const sourceString = `${source.repoURL}/${source.path || source.chart}`; + const sourceString = source ? `${source.repoURL}/${source.path || source.chart}` : ''; return (
    {sourceString}
    diff --git a/ui/src/app/applications/components/applications-list/applications-table.tsx b/ui/src/app/applications/components/applications-list/applications-table.tsx index a024059e16e5b..4952a0f08fb9a 100644 --- a/ui/src/app/applications/components/applications-list/applications-table.tsx +++ b/ui/src/app/applications/components/applications-list/applications-table.tsx @@ -59,7 +59,7 @@ export const ApplicationsTable = (props: { applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
    ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}> + onClick={e => ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}>
    diff --git a/ui/src/app/applications/components/applications-list/applications-tiles.tsx b/ui/src/app/applications/components/applications-list/applications-tiles.tsx index 3467d3b952a87..fb6b1f158bd4a 100644 --- a/ui/src/app/applications/components/applications-list/applications-tiles.tsx +++ b/ui/src/app/applications/components/applications-list/applications-tiles.tsx @@ -108,6 +108,7 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
    {applications.map((app, i) => { const source = getAppDefaultSource(app); + const targetRevision = source ? source.targetRevision || 'HEAD' : 'Unknown'; return (
    - ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e}) + ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e}) }>
    0 ? 'columns small-10' : 'columns small-11'}> - + {AppUtils.appQualifiedName(app, useAuthSettingsCtx?.appsInAnyNamespaceEnabled)} @@ -208,8 +209,8 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat Repository:
    - - {source.repoURL} + + {source?.repoURL}
    @@ -217,22 +218,22 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
    Target Revision:
    -
    {source.targetRevision || 'HEAD'}
    +
    {targetRevision}
    - {source.path && ( + {source?.path && (
    Path:
    -
    {source.path}
    +
    {source?.path}
    )} - {source.chart && ( + {source?.chart && (
    Chart:
    -
    {source.chart}
    +
    {source?.chart}
    )}
    diff --git a/ui/src/app/applications/components/pod-logs-viewer/fullscreen-button.tsx b/ui/src/app/applications/components/pod-logs-viewer/fullscreen-button.tsx index 30d37c96c506c..89e266c8577c3 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/fullscreen-button.tsx +++ b/ui/src/app/applications/components/pod-logs-viewer/fullscreen-button.tsx @@ -12,10 +12,15 @@ export const FullscreenButton = ({ kind, name, namespace, - podName + podName, + viewPodNames, + viewTimestamps, + follow, + showPreviousLogs }: PodLogsProps & {fullscreen?: boolean}) => { const fullscreenURL = - `/applications/${applicationNamespace}/${applicationName}/${namespace}/${containerName}/logs?` + `podName=${podName}&group=${group}&kind=${kind}&name=${name}`; + `/applications/${applicationNamespace}/${applicationName}/${namespace}/${containerName}/logs?` + + `podName=${podName}&group=${group}&kind=${kind}&name=${name}&viewPodNames=${viewPodNames}&viewTimestamps=${viewTimestamps}&follow=${follow}&showPreviousLogs=${showPreviousLogs}`; return ( !fullscreen && ( diff --git a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx index 609afd14dd4fa..e8cdca83f63b8 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx +++ b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx @@ -40,6 +40,10 @@ export interface PodLogsProps { containerGroups?: any[]; onClickContainer?: (group: any, i: number, tab: string) => void; fullscreen?: boolean; + viewPodNames?: boolean; + viewTimestamps?: boolean; + follow?: boolean; + showPreviousLogs?: boolean; } // ansi colors, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors @@ -86,11 +90,27 @@ export const PodsLogsViewer = (props: PodLogsProps) => { const [logs, setLogs] = useState([]); const logsContainerRef = useRef(null); - useEffect(() => { - if (viewPodNames) { - setViewTimestamps(false); + const setWithQueryParams = void>(key: string, cb: T) => { + return (val => { + cb(val); + queryParams.set(key, val.toString()); + history.replaceState(null, '', `${location.pathname}?${queryParams}`); + }) as T; + }; + + const setViewPodNamesWithQueryParams = setWithQueryParams('viewPodNames', setViewPodNames); + const setViewTimestampsWithQueryParams = setWithQueryParams('viewTimestamps', setViewTimestamps); + const setFollowWithQueryParams = setWithQueryParams('follow', setFollow); + const setPreviousLogsWithQueryParams = setWithQueryParams('showPreviousLogs', setPreviousLogs); + const setTailWithQueryParams = setWithQueryParams('tail', setTail); + const setFilterWithQueryParams = setWithQueryParams('filterText', setFilter); + + const onToggleViewPodNames = (val: boolean) => { + setViewPodNamesWithQueryParams(val); + if (val) { + setViewTimestampsWithQueryParams(false); } - }, [viewPodNames]); + }; useEffect(() => { // https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript @@ -165,32 +185,32 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
    - + {follow && } - + {!follow && ( <> setSinceSeconds(n)} /> - + )} - + - - + + - +
    diff --git a/ui/src/app/applications/components/resource-details/resource-details.tsx b/ui/src/app/applications/components/resource-details/resource-details.tsx index 59774fa459872..79bbce2c133ae 100644 --- a/ui/src/app/applications/components/resource-details/resource-details.tsx +++ b/ui/src/app/applications/components/resource-details/resource-details.tsx @@ -284,7 +284,8 @@ export const ResourceDetails = (props: ResourceDetailsProps) => { const logsAllowed = await services.accounts.canI('logs', 'get', application.spec.project + '/' + application.metadata.name); const execAllowed = execEnabled && (await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name)); const links = await services.applications.getResourceLinks(application.metadata.name, application.metadata.namespace, selectedNode).catch(() => null); - return {controlledState, liveState, events, podState, execEnabled, execAllowed, logsAllowed, links, childResources}; + const resourceActionsMenuItems = await AppUtils.getResourceActionsMenuItems(selectedNode, application.metadata, appContext); + return {controlledState, liveState, events, podState, execEnabled, execAllowed, logsAllowed, links, childResources, resourceActionsMenuItems}; }}> {data => ( @@ -314,15 +315,17 @@ export const ResourceDetails = (props: ResourceDetailsProps) => { className='argo-button argo-button--base'> DELETE - ( - - )}> - {() => 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..54ca382cdcbd4 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -496,7 +496,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 +683,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 +740,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)) { @@ -993,23 +987,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 +1057,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 +1095,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 +1120,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 +1167,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; 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 6c715077cc9cc..b363a4a934d63 100644 --- a/ui/src/app/login/components/utils.ts +++ b/ui/src/app/login/components/utils.ts @@ -4,8 +4,8 @@ import { authorizationCodeGrantRequest, calculatePKCECodeChallenge, discoveryRequest, - expectNoState, generateRandomCodeVerifier, + generateRandomState, isOAuth2Error, parseWwwAuthenticateChallenges, processAuthorizationCodeOpenIDResponse, @@ -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)); @@ -22,10 +23,16 @@ export const PKCECodeVerifier = { unset: () => sessionStorage.removeItem(window.btoa('code_verifier')) }; +export const PKCEState = { + get: () => sessionStorage.getItem(window.btoa('pkce_session_id')), + set: (sessionId: string) => sessionStorage.setItem(window.btoa('pkce_session_id'), sessionId), + unset: () => sessionStorage.removeItem(window.btoa('pkce_session_id')) +}; + export const getPKCERedirectURI = () => { const currentOrigin = new URL(window.location.origin); - currentOrigin.pathname = '/pkce/verify'; + currentOrigin.pathname = requests.toAbsURL('/pkce/verify'); return currentOrigin; }; @@ -70,10 +77,18 @@ 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'); } + const state = generateRandomState(); + const codeVerifier = generateRandomCodeVerifier(); const codeChallange = await calculatePKCECodeChallenge(codeVerifier); @@ -86,8 +101,10 @@ export const pkceLogin = async (oidcConfig: AuthSettings['oidcConfig'], redirect authorizationServerConsentScreen.searchParams.set('redirect_uri', redirectURI); authorizationServerConsentScreen.searchParams.set('response_type', 'code'); authorizationServerConsentScreen.searchParams.set('scope', oidcConfig.scopes.join(' ')); + authorizationServerConsentScreen.searchParams.set('state', state); PKCECodeVerifier.set(codeVerifier); + PKCEState.set(state); window.location.replace(authorizationServerConsentScreen.toString()); }; @@ -110,10 +127,6 @@ export const pkceCallback = async (queryParams: string, oidcConfig: AuthSettings throw new PKCELoginError('No code in query parameters'); } - if (callbackQueryParams.get('state') === '') { - callbackQueryParams.delete('state'); - } - const {authorizationServer} = await validateAndGetOIDCForPKCE(oidcConfig); const client: Client = { @@ -121,7 +134,9 @@ export const pkceCallback = async (queryParams: string, oidcConfig: AuthSettings token_endpoint_auth_method: 'none' }; - const params = validateAuthResponse(authorizationServer, client, callbackQueryParams, expectNoState); + const expectedState = PKCEState.get(); + + const params = validateAuthResponse(authorizationServer, client, callbackQueryParams, expectedState); if (isOAuth2Error(params)) { throw new PKCELoginError('Error validating auth response'); @@ -145,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 2f78d706c37cf..96110c2ff9cee 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -220,7 +220,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..613d469c81612 100644 --- a/ui/src/app/settings/components/repo-details/repo-details.tsx +++ b/ui/src/app/settings/components/repo-details/repo-details.tsx @@ -17,6 +17,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,13 +34,6 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New } ]; - if (repository.name) { - items.splice(1, 0, { - title: 'NAME', - view: repository.name - }); - } - if (repository.project) { items.splice(repository.name ? 2 : 1, 0, { title: 'Project', @@ -86,6 +84,7 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New })} save={async input => { const params: NewHTTPSRepoParams = {...newRepo}; + 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..876bf5378f957 100644 --- a/ui/src/app/settings/components/repos-list/repos-list.tsx +++ b/ui/src/app/settings/components/repos-list/repos-list.tsx @@ -470,9 +470,14 @@ export class ReposList extends React.Component<
    - {formApi.getFormState().values.type === 'helm' && ( + {(formApi.getFormState().values.type === 'helm' || formApi.getFormState().values.type === 'git') && (
    - +
    )}
    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 69cec01076796..c9d37184539d3 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -324,12 +324,12 @@ export const SyncStatuses: {[key: string]: SyncStatusCode} = { export type HealthStatusCode = 'Unknown' | 'Progressing' | 'Healthy' | 'Suspended' | 'Degraded' | 'Missing'; export const HealthStatuses: {[key: string]: HealthStatusCode} = { - Unknown: 'Unknown', Progressing: 'Progressing', Suspended: 'Suspended', Healthy: 'Healthy', Degraded: 'Degraded', - Missing: 'Missing' + Missing: 'Missing', + Unknown: 'Unknown' }; export interface HealthStatus { @@ -354,6 +354,7 @@ export interface ResourceStatus { createdAt?: models.Time; hook?: boolean; requiresPruning?: boolean; + requiresDeletionConfirmation?: boolean; syncWave?: number; orphaned?: boolean; } @@ -985,3 +986,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..48fb8308eab38 100644 --- a/ui/src/app/shared/services/repo-service.ts +++ b/ui/src/app/shared/services/repo-service.ts @@ -224,7 +224,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/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 264635d4f66f2..000ee1b8fcade 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2884,7 +2884,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" @@ -2893,7 +2893,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" @@ -4193,9 +4192,9 @@ domhandler@^4.0.0, domhandler@^4.2.0: domelementtype "^2.2.0" dompurify@^2.2.8: - version "2.3.6" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875" - integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg== + version "2.5.6" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.6.tgz#8402b501611eaa7fb3786072297fcbe2787f8592" + integrity sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ== domutils@^2.5.2, domutils@^2.6.0: version "2.7.0" @@ -5651,9 +5650,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" @@ -6133,7 +6132,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" @@ -7654,9 +7653,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..580e4cd06935d 100644 --- a/util/app/discovery/discovery.go +++ b/util/app/discovery/discovery.go @@ -173,9 +173,12 @@ func cmpSupports(ctx context.Context, pluginSockFilePath, appPath, repoPath, fil 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 + } + 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..8fb4eba2f3430 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -329,7 +329,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 { @@ -423,8 +426,7 @@ func validateRepo(ctx context.Context, db, permittedHelmRepos, helmOptions, - app.Name, - app.Spec.Destination, + app, proj, sources, repoClient, @@ -434,7 +436,6 @@ func validateRepo(ctx context.Context, permittedHelmCredentials, enabledSourceTypes, settingsMgr, - app.Spec.HasMultipleSources(), refSources)...) return conditions, nil @@ -706,8 +707,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 +716,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 +752,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 +768,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) diff --git a/util/argo/argo_test.go b/util/argo/argo_test.go index b2c684c660c1f..74db80a0c198c 100644 --- a/util/argo/argo_test.go +++ b/util/argo/argo_test.go @@ -893,8 +893,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 +906,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) }) @@ -973,7 +971,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()) }) diff --git a/util/argo/audit_logger.go b/util/argo/audit_logger.go index ba0d483922b9c..cffef2d64d75d 100644 --- a/util/argo/audit_logger.go +++ b/util/argo/audit_logger.go @@ -18,9 +18,10 @@ import ( ) type AuditLogger struct { - kIf kubernetes.Interface - component string - ns string + kIf kubernetes.Interface + component string + ns string + enableEventLog map[string]bool } type EventInfo struct { @@ -95,7 +96,15 @@ func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, i } } +func (l *AuditLogger) enableK8SEventLog(info EventInfo) bool { + return l.enableEventLog["all"] || l.enableEventLog[info.Reason] +} + func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, message, user string, eventLabels map[string]string) { + if !l.enableK8SEventLog(info) { + return + } + objectMeta := ObjectRef{ Name: app.ObjectMeta.Name, Namespace: app.ObjectMeta.Namespace, @@ -113,6 +122,10 @@ func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, mes } func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInfo, message, user string) { + if !l.enableK8SEventLog(info) { + return + } + objectMeta := ObjectRef{ Name: app.ObjectMeta.Name, Namespace: app.ObjectMeta.Namespace, @@ -127,6 +140,10 @@ func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInf } func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInfo, message, user string) { + if !l.enableK8SEventLog(info) { + return + } + objectMeta := ObjectRef{ Name: res.ResourceRef.Name, Namespace: res.ResourceRef.Namespace, @@ -145,6 +162,10 @@ func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInf } func (l *AuditLogger) LogAppProjEvent(proj *v1alpha1.AppProject, info EventInfo, message, user string) { + if !l.enableK8SEventLog(info) { + return + } + objectMeta := ObjectRef{ Name: proj.ObjectMeta.Name, Namespace: proj.ObjectMeta.Namespace, @@ -158,10 +179,35 @@ func (l *AuditLogger) LogAppProjEvent(proj *v1alpha1.AppProject, info EventInfo, l.logEvent(objectMeta, v1alpha1.AppProjectSchemaGroupVersionKind, info, message, nil, nil) } -func NewAuditLogger(ns string, kIf kubernetes.Interface, component string) *AuditLogger { +func NewAuditLogger(ns string, kIf kubernetes.Interface, component string, enableK8sEvent []string) *AuditLogger { return &AuditLogger{ - ns: ns, - kIf: kIf, - component: component, + ns: ns, + kIf: kIf, + component: component, + enableEventLog: setK8sEventList(enableK8sEvent), } } + +func setK8sEventList(enableK8sEvent []string) map[string]bool { + enableK8sEventList := make(map[string]bool) + + for _, event := range enableK8sEvent { + if event == "all" { + enableK8sEventList = map[string]bool{ + "all": true, + } + return enableK8sEventList + } else if event == "none" { + enableK8sEventList = map[string]bool{} + return enableK8sEventList + } + + enableK8sEventList[event] = true + } + + return enableK8sEventList +} + +func DefaultEnableEventList() []string { + return []string{"all"} +} diff --git a/util/argo/audit_logger_test.go b/util/argo/audit_logger_test.go index 17fcaf366c1d3..a0c5714fb3266 100644 --- a/util/argo/audit_logger_test.go +++ b/util/argo/audit_logger_test.go @@ -14,6 +14,13 @@ import ( argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) +const ( + _somecomponent = "somecomponent" + _test = "test" +) + +var testEnableEventLog []string = []string{_somecomponent, _test} + // Helper to capture log entries generated by the logger and return it as string func captureLogEntries(run func()) string { f := log.StandardLogger().Formatter @@ -29,12 +36,12 @@ func captureLogEntries(run func()) string { } func TestNewAuditLogger(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent") + logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) } func TestLogAppProjEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent") + logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) proj := argoappv1.AppProject{ @@ -50,7 +57,7 @@ func TestLogAppProjEvent(t *testing.T) { } ei := EventInfo{ - Reason: "test", + Reason: _test, Type: "info", } @@ -63,10 +70,19 @@ func TestLogAppProjEvent(t *testing.T) { assert.Contains(t, output, "reason=test") assert.Contains(t, output, "type=info") assert.Contains(t, output, "msg=\"This is a test message\"") + + ei.Reason = "Unknown" + + // If K8s Event Disable Log + output = captureLogEntries(func() { + logger.LogAppProjEvent(&proj, ei, "This is a test message", "") + }) + + assert.Empty(t, output) } func TestLogAppEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent") + logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) app := argoappv1.Application{ @@ -85,7 +101,7 @@ func TestLogAppEvent(t *testing.T) { } ei := EventInfo{ - Reason: "test", + Reason: _test, Type: "info", } @@ -100,10 +116,19 @@ func TestLogAppEvent(t *testing.T) { assert.Contains(t, output, "reason=test") assert.Contains(t, output, "type=info") assert.Contains(t, output, "msg=\"This is a test message\"") + + ei.Reason = "Unknown" + + // If K8s Event Disable Log + output = captureLogEntries(func() { + logger.LogAppEvent(&app, ei, "This is a test message", "", nil) + }) + + assert.Empty(t, output) } func TestLogResourceEvent(t *testing.T) { - logger := NewAuditLogger("default", fake.NewSimpleClientset(), "somecomponent") + logger := NewAuditLogger("default", fake.NewSimpleClientset(), _somecomponent, testEnableEventLog) assert.NotNil(t, logger) res := argoappv1.ResourceNode{ @@ -118,7 +143,7 @@ func TestLogResourceEvent(t *testing.T) { } ei := EventInfo{ - Reason: "test", + Reason: _test, Type: "info", } @@ -131,4 +156,13 @@ func TestLogResourceEvent(t *testing.T) { assert.Contains(t, output, "reason=test") assert.Contains(t, output, "type=info") assert.Contains(t, output, "msg=\"This is a test message\"") + + ei.Reason = "Unknown" + + // If K8s Event Disable Log + output = captureLogEntries(func() { + logger.LogResourceEvent(&res, ei, "This is a test message", "") + }) + + assert.Empty(t, output) } 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/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_test.go b/util/cache/redis_test.go index e0314cefaf63a..d60c7ea268e2c 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") }) } 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/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_test.go b/util/db/cluster_test.go index b430db851664d..50cca2eff5d55 100644 --- a/util/db/cluster_test.go +++ b/util/db/cluster_test.go @@ -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() diff --git a/util/db/db_test.go b/util/db/db_test.go index 38d56a4bceac1..2e8560459c4b2 100644 --- a/util/db/db_test.go +++ b/util/db/db_test.go @@ -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/exec/exec_test.go b/util/exec/exec_test.go index a3ae4888f2cf4..4597b7213ef23 100644 --- a/util/exec/exec_test.go +++ b/util/exec/exec_test.go @@ -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..81bc87f081e43 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -631,14 +631,9 @@ func (m *nativeGitClient) lsRemote(revision string) (string, error) { 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 +679,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 +731,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 +746,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) } diff --git a/util/git/client_test.go b/util/git/client_test.go index c2f8061a1c2f0..a953e8bf214e1 100644 --- a/util/git/client_test.go +++ b/util/git/client_test.go @@ -7,6 +7,7 @@ import ( "path" "path/filepath" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -173,6 +174,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) @@ -296,3 +439,43 @@ 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) +} diff --git a/util/git/git_test.go b/util/git/git_test.go index bfa2905e7f518..d507c728c0fde 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") } }) } 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/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..cae4574e2e86b 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" @@ -214,6 +215,91 @@ 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 + } + + 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) + err := json.NewEncoder(w).Encode(responseTags) + if err != nil { + t.Fatal(err) + } + })) + 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) @@ -224,7 +310,7 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { return } - t.Logf("authorization received %s", authorization) + assert.Equal(t, expectedAuthorization, authorization) responseTags := TagsList{ Tags: []string{ @@ -248,6 +334,13 @@ func TestGetTagsFromURLPrivateRepoAuthentication(t *testing.T) { 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 +367,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..9a5ba948c3779 100644 --- a/util/helm/cmd.go +++ b/util/helm/cmd.go @@ -340,21 +340,39 @@ type TemplateOpts struct { // spec.source.helm.values/valuesObject. ExtraValues pathutil.ResolvedFilePath SkipCrds 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 +409,9 @@ func (c *Cmd) template(chartPath string, opts *TemplateOpts) (string, string, er if !opts.SkipCrds { args = append(args, "--include-crds") } + 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/tar_test.go b/util/io/files/tar_test.go index f8b140b5dc658..ec717c36a3ab7 100644 --- a/util/io/files/tar_test.go +++ b/util/io/files/tar_test.go @@ -195,8 +195,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 +251,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/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/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..c4c571748ac5b 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("force-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..64a65cd0bc455 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+" --force-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+" --force-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+" --force-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..ba1bbbf0d0b43 100644 --- a/util/lua/custom_actions_test.go +++ b/util/lua/custom_actions_test.go @@ -209,6 +209,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/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/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/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/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..d41124d9a15e4 100644 --- a/util/session/sessionmanager_test.go +++ b/util/session/sessionmanager_test.go @@ -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'") }) } @@ -277,7 +273,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: true, verifiedClaims: &claimsMock{}, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, { @@ -286,7 +282,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: false, verifiedClaims: nil, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, { @@ -295,7 +291,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: false, verifiedClaims: &claimsMock{}, verifyTokenErr: nil, - expectedStatusCode: 400, + expectedStatusCode: http.StatusBadRequest, expectedResponseBody: nil, }, { @@ -304,7 +300,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 +309,7 @@ func TestSessionManager_WithAuthMiddleware(t *testing.T) { cookieHeader: true, verifiedClaims: nil, verifyTokenErr: nil, - expectedStatusCode: 200, + expectedStatusCode: http.StatusOK, expectedResponseBody: strPointer("Ok"), }, } @@ -538,8 +534,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) { diff --git a/util/settings/settings.go b/util/settings/settings.go index 7d192d9cb9461..516116f0ecd99 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"` @@ -451,6 +451,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 +461,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. @@ -535,6 +539,9 @@ const ( const ( // default max webhook payload size is 1GB defaultMaxWebhookPayloadSize = int64(1) * 1024 * 1024 * 1024 + + // application sync with impersonation feature is disabled by default. + defaultImpersonationEnabledFlag = false ) var sourceTypeToEnableGenerationKey = map[v1alpha1.ApplicationSourceType]string{ @@ -792,6 +799,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 +921,7 @@ func (mgr *SettingsManager) GetIsIgnoreResourceUpdatesEnabled() (bool, error) { } if argoCDCM.Data[resourceIgnoreResourceUpdatesEnabledKey] == "" { - return false, nil + return true, nil } return strconv.ParseBool(argoCDCM.Data[resourceIgnoreResourceUpdatesEnabledKey]) @@ -1524,10 +1539,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 +2343,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 +2384,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..1a220bc2f063a 100644 --- a/util/settings/settings_test.go +++ b/util/settings/settings_test.go @@ -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"}}) @@ -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) @@ -1221,8 +1274,7 @@ 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) { @@ -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.NewSimpleClientset() + 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/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/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..892fbea2038f6 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 @@ -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)